down integration from internal
diff --git a/Makefile.am b/Makefile.am
index 5af3f31..688486b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -791,6 +791,7 @@
python/google/protobuf/internal/descriptor_test.py \
python/google/protobuf/internal/encoder.py \
python/google/protobuf/internal/enum_type_wrapper.py \
+ python/google/protobuf/internal/extension_dict.py \
python/google/protobuf/internal/factory_test1.proto \
python/google/protobuf/internal/factory_test2.proto \
python/google/protobuf/internal/file_options_test.proto \
diff --git a/cmake/libprotobuf-lite.cmake b/cmake/libprotobuf-lite.cmake
index 344df28..890074f 100644
--- a/cmake/libprotobuf-lite.cmake
+++ b/cmake/libprotobuf-lite.cmake
@@ -1,4 +1,5 @@
set(libprotobuf_lite_files
+ ${protobuf_source_dir}/src/google/protobuf/any_lite.cc
${protobuf_source_dir}/src/google/protobuf/arena.cc
${protobuf_source_dir}/src/google/protobuf/extension_set.cc
${protobuf_source_dir}/src/google/protobuf/generated_message_table_driven_lite.cc
diff --git a/conformance/ConformanceJava.java b/conformance/ConformanceJava.java
index 008f3bc..478b186 100644
--- a/conformance/ConformanceJava.java
+++ b/conformance/ConformanceJava.java
@@ -249,13 +249,30 @@
break;
}
case TEXT_PAYLOAD: {
- try {
- TestMessagesProto3.TestAllTypesProto3.Builder builder =
- TestMessagesProto3.TestAllTypesProto3.newBuilder();
- TextFormat.merge(request.getTextPayload(), builder);
- testMessage = builder.build();
- } catch (TextFormat.ParseException e) {
- return Conformance.ConformanceResponse.newBuilder().setParseError(e.getMessage()).build();
+ if (isProto3) {
+ try {
+ TestMessagesProto3.TestAllTypesProto3.Builder builder =
+ TestMessagesProto3.TestAllTypesProto3.newBuilder();
+ TextFormat.merge(request.getTextPayload(), builder);
+ testMessage = builder.build();
+ } catch (TextFormat.ParseException e) {
+ return Conformance.ConformanceResponse.newBuilder()
+ .setParseError(e.getMessage())
+ .build();
+ }
+ } else if (isProto2) {
+ try {
+ TestMessagesProto2.TestAllTypesProto2.Builder builder =
+ TestMessagesProto2.TestAllTypesProto2.newBuilder();
+ TextFormat.merge(request.getTextPayload(), builder);
+ testMessage = builder.build();
+ } catch (TextFormat.ParseException e) {
+ return Conformance.ConformanceResponse.newBuilder()
+ .setParseError(e.getMessage())
+ .build();
+ }
+ } else {
+ throw new RuntimeException("Protobuf request doesn't have specific payload type.");
}
break;
}
diff --git a/conformance/Makefile.am b/conformance/Makefile.am
index f45bfe3..18ac673 100644
--- a/conformance/Makefile.am
+++ b/conformance/Makefile.am
@@ -207,9 +207,11 @@
conformance_test_runner_LDADD = $(top_srcdir)/src/libprotobuf.la
conformance_test_runner_SOURCES = conformance_test.h conformance_test.cc \
- binary_json_conformance_main.cc \
+ conformance_test_main.cc \
binary_json_conformance_suite.h \
binary_json_conformance_suite.cc \
+ text_format_conformance_suite.h \
+ text_format_conformance_suite.cc \
conformance_test_runner.cc \
third_party/jsoncpp/json.h \
third_party/jsoncpp/jsoncpp.cpp
diff --git a/conformance/binary_json_conformance_suite.cc b/conformance/binary_json_conformance_suite.cc
index 45d9c16..9506ff1 100644
--- a/conformance/binary_json_conformance_suite.cc
+++ b/conformance/binary_json_conformance_suite.cc
@@ -681,6 +681,20 @@
}
void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
+ // Hack to get the list of test failures based on whether
+ // GOOGLE3_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER is enabled or not.
+ conformance::FailureSet failure_set;
+ ConformanceRequest req;
+ ConformanceResponse res;
+ req.set_message_type(failure_set.GetTypeName());
+ req.set_protobuf_payload("");
+ req.set_requested_output_format(conformance::WireFormat::PROTOBUF);
+ RunTest("FindFailures", req, &res);
+ GOOGLE_CHECK(failure_set.MergeFromString(res.protobuf_payload()));
+ for (const string& failure : failure_set.failure()) {
+ AddExpectedFailedTest(failure);
+ }
+
type_resolver_.reset(NewTypeResolverForDescriptorPool(
kTypeUrlPrefix, DescriptorPool::generated_pool()));
type_url_ = GetTypeUrl(TestAllTypesProto3::descriptor());
diff --git a/conformance/conformance_python.py b/conformance/conformance_python.py
index 623f8f5..5c4f900 100755
--- a/conformance/conformance_python.py
+++ b/conformance/conformance_python.py
@@ -65,7 +65,12 @@
# TODO(gerbens): Remove, this is a hack to detect if the old vs new
# parser is used by the cpp code. Relying on a bug in the old parser.
hack_proto = test_messages_proto2_pb2.TestAllTypesProto2()
- if hack_proto.ParseFromString(b"\322\002\001"):
+ old_parser = True
+ try:
+ hack_proto.ParseFromString(b"\322\002\001")
+ except message.DecodeError as e:
+ old_parser = False
+ if old_parser:
# the string above is one of the failing conformance test strings of the
# old parser. If we succeed the c++ implementation is using the old
# parser so we add the list of failing conformance tests.
diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc
index b743e8e..221464c 100644
--- a/conformance/conformance_test.cc
+++ b/conformance/conformance_test.cc
@@ -361,6 +361,10 @@
return "";
}
+void ConformanceTestSuite::AddExpectedFailedTest(const std::string& test_name) {
+ expected_to_fail_.insert(test_name);
+}
+
bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
std::string* output, const string& filename,
conformance::FailureSet* failure_list) {
@@ -374,17 +378,10 @@
output_ = "\nCONFORMANCE TEST BEGIN ====================================\n\n";
- ConformanceRequest req;
- ConformanceResponse res;
- req.set_message_type(failure_list->GetTypeName());
- req.set_protobuf_payload("");
- req.set_requested_output_format(conformance::WireFormat::PROTOBUF);
- RunTest("FindFailures", req, &res);
- GOOGLE_CHECK(failure_list->MergeFromString(res.protobuf_payload()));
failure_list_filename_ = filename;
expected_to_fail_.clear();
for (const string& failure : failure_list->failure()) {
- expected_to_fail_.insert(failure);
+ AddExpectedFailedTest(failure);
}
RunSuiteImpl();
diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h
index e0bc1e0..b64943d 100644
--- a/conformance/conformance_test.h
+++ b/conformance/conformance_test.h
@@ -84,8 +84,9 @@
// over a pipe.
class ForkPipeRunner : public ConformanceTestRunner {
public:
+ // Note: Run() doesn't take ownership of the pointers inside suites.
static int Run(int argc, char *argv[],
- ConformanceTestSuite* suite);
+ const std::vector<ConformanceTestSuite*>& suites);
ForkPipeRunner(const std::string &executable)
: child_pid_(-1), executable_(executable) {}
@@ -139,7 +140,10 @@
//
class ConformanceTestSuite {
public:
- ConformanceTestSuite() : verbose_(false), enforce_recommended_(false) {}
+ ConformanceTestSuite()
+ : verbose_(false),
+ enforce_recommended_(false),
+ failure_list_flag_name_("--failure_list") {}
virtual ~ConformanceTestSuite() {}
void SetVerbose(bool verbose) { verbose_ = verbose; }
@@ -156,6 +160,16 @@
enforce_recommended_ = value;
}
+ // Gets the flag name to the failure list file.
+ // By default, this would return --failure_list
+ string GetFailureListFlagName() {
+ return failure_list_flag_name_;
+ }
+
+ void SetFailureListFlagName(const std::string& failure_list_flag_name) {
+ failure_list_flag_name_ = failure_list_flag_name;
+ }
+
// Run all the conformance tests against the given test runner.
// Test output will be stored in "output".
//
@@ -259,6 +273,8 @@
const conformance::ConformanceRequest& request,
conformance::ConformanceResponse* response);
+ void AddExpectedFailedTest(const std::string& test_name);
+
virtual void RunSuiteImpl() = 0;
ConformanceTestRunner* runner_;
@@ -267,6 +283,7 @@
bool verbose_;
bool enforce_recommended_;
std::string output_;
+ std::string failure_list_flag_name_;
std::string failure_list_filename_;
// The set of test names that are expected to fail in this run, but haven't
diff --git a/conformance/conformance_test_main.cc b/conformance/conformance_test_main.cc
new file mode 100644
index 0000000..c7ac9fc
--- /dev/null
+++ b/conformance/conformance_test_main.cc
@@ -0,0 +1,40 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "binary_json_conformance_suite.h"
+#include "conformance_test.h"
+#include "text_format_conformance_suite.h"
+
+int main(int argc, char *argv[]) {
+ google::protobuf::BinaryAndJsonConformanceSuite binary_and_json_suite;
+ google::protobuf::TextFormatConformanceTestSuite text_format_suite;
+ return google::protobuf::ForkPipeRunner::Run(
+ argc, argv, {&binary_and_json_suite, &text_format_suite});
+}
diff --git a/conformance/conformance_test_runner.cc b/conformance/conformance_test_runner.cc
index 0279bb6..e7aa0a5 100644
--- a/conformance/conformance_test_runner.cc
+++ b/conformance/conformance_test_runner.cc
@@ -120,6 +120,19 @@
fprintf(stderr,
" line. Use '#' for comments.\n");
fprintf(stderr,
+ " --text_format_failure_list <filename> Use to specify list \n");
+ fprintf(stderr,
+ " of tests that are expected to \n");
+ fprintf(stderr,
+ " fail in the \n");
+ fprintf(stderr,
+ " text_format_conformance_suite. \n");
+ fprintf(stderr,
+ " File should contain one test name \n");
+ fprintf(stderr,
+ " per line. Use '#' for comments.\n");
+
+ fprintf(stderr,
" --enforce_recommended Enforce that recommended test\n");
fprintf(stderr,
" cases are also passing. Specify\n");
@@ -175,41 +188,56 @@
}
int ForkPipeRunner::Run(
- int argc, char *argv[], ConformanceTestSuite* suite) {
- char *program;
- string failure_list_filename;
- conformance::FailureSet failure_list;
-
- for (int arg = 1; arg < argc; ++arg) {
- if (strcmp(argv[arg], "--failure_list") == 0) {
- if (++arg == argc) UsageError();
- failure_list_filename = argv[arg];
- ParseFailureList(argv[arg], &failure_list);
- } else if (strcmp(argv[arg], "--verbose") == 0) {
- suite->SetVerbose(true);
- } else if (strcmp(argv[arg], "--enforce_recommended") == 0) {
- suite->SetEnforceRecommended(true);
- } else if (argv[arg][0] == '-') {
- fprintf(stderr, "Unknown option: %s\n", argv[arg]);
- UsageError();
- } else {
- if (arg != argc - 1) {
- fprintf(stderr, "Too many arguments.\n");
- UsageError();
- }
- program = argv[arg];
- }
+ int argc, char *argv[], const std::vector<ConformanceTestSuite*>& suites) {
+ if (suites.empty()) {
+ fprintf(stderr, "No test suites found.\n");
+ return EXIT_FAILURE;
}
+ bool all_ok = true;
+ for (ConformanceTestSuite* suite : suites) {
+ char *program;
+ string failure_list_filename;
+ conformance::FailureSet failure_list;
- ForkPipeRunner runner(program);
+ for (int arg = 1; arg < argc; ++arg) {
+ if (strcmp(argv[arg], suite->GetFailureListFlagName().c_str()) == 0) {
+ if (++arg == argc) UsageError();
+ failure_list_filename = argv[arg];
+ ParseFailureList(argv[arg], &failure_list);
+ } else if (strcmp(argv[arg], "--verbose") == 0) {
+ suite->SetVerbose(true);
+ } else if (strcmp(argv[arg], "--enforce_recommended") == 0) {
+ suite->SetEnforceRecommended(true);
+ } else if (argv[arg][0] == '-') {
+ bool recognized_flag = false;
+ for (ConformanceTestSuite* suite : suites) {
+ if (strcmp(argv[arg], suite->GetFailureListFlagName().c_str()) == 0) {
+ if (++arg == argc) UsageError();
+ recognized_flag = true;
+ }
+ }
+ if (!recognized_flag) {
+ fprintf(stderr, "Unknown option: %s\n", argv[arg]);
+ UsageError();
+ }
+ } else {
+ if (arg != argc - 1) {
+ fprintf(stderr, "Too many arguments.\n");
+ UsageError();
+ }
+ program = argv[arg];
+ }
+ }
- std::string output;
- bool ok =
- suite->RunSuite(&runner, &output, failure_list_filename, &failure_list);
+ ForkPipeRunner runner(program);
- fwrite(output.c_str(), 1, output.size(), stderr);
+ std::string output;
+ all_ok = all_ok &&
+ suite->RunSuite(&runner, &output, failure_list_filename, &failure_list);
- return ok ? EXIT_SUCCESS : EXIT_FAILURE;
+ fwrite(output.c_str(), 1, output.size(), stderr);
+ }
+ return all_ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
// TODO(haberman): make this work on Windows, instead of using these
diff --git a/conformance/failure_list_python.txt b/conformance/failure_list_python.txt
index ce7cdec..e3ce7af 100644
--- a/conformance/failure_list_python.txt
+++ b/conformance/failure_list_python.txt
@@ -19,4 +19,3 @@
Required.Proto3.ProtobufInput.IllegalZeroFieldNum_Case_1
Required.Proto3.ProtobufInput.IllegalZeroFieldNum_Case_2
Required.Proto3.ProtobufInput.IllegalZeroFieldNum_Case_3
-Required.Proto3.JsonInput.EmptyFieldMask.ProtobufOutput
diff --git a/conformance/failure_list_python_cpp.txt b/conformance/failure_list_python_cpp.txt
index 4531946..59a969d 100644
--- a/conformance/failure_list_python_cpp.txt
+++ b/conformance/failure_list_python_cpp.txt
@@ -20,4 +20,3 @@
Required.Proto3.JsonInput.FloatFieldTooSmall
Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
Required.Proto3.JsonInput.TimestampJsonInputLowercaseT
-Required.Proto3.JsonInput.EmptyFieldMask.ProtobufOutput
diff --git a/conformance/text_format_conformance_suite.cc b/conformance/text_format_conformance_suite.cc
new file mode 100644
index 0000000..4483ffb
--- /dev/null
+++ b/conformance/text_format_conformance_suite.cc
@@ -0,0 +1,240 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "text_format_conformance_suite.h"
+
+#include "conformance_test.h"
+
+#include <google/protobuf/any.pb.h>
+#include <google/protobuf/test_messages_proto2.pb.h>
+#include <google/protobuf/test_messages_proto3.pb.h>
+#include <google/protobuf/text_format.h>
+
+using conformance::ConformanceRequest;
+using conformance::ConformanceResponse;
+using conformance::WireFormat;
+using google::protobuf::Message;
+using google::protobuf::TextFormat;
+using protobuf_test_messages::proto2::TestAllTypesProto2;
+using protobuf_test_messages::proto3::TestAllTypesProto3;
+using std::string;
+
+namespace google {
+namespace protobuf {
+
+TextFormatConformanceTestSuite::TextFormatConformanceTestSuite() {
+ SetFailureListFlagName("--text_format_failure_list");
+}
+
+bool TextFormatConformanceTestSuite::ParseTextFormatResponse(
+ const ConformanceResponse& response, Message* test_message) {
+ if (!TextFormat::ParseFromString(response.text_payload(), test_message)) {
+ GOOGLE_LOG(ERROR) << "INTERNAL ERROR: internal text->protobuf transcode "
+ << "yielded unparseable proto. Text payload: "
+ << response.text_payload();
+ return false;
+ }
+
+ return true;
+}
+
+bool TextFormatConformanceTestSuite::ParseResponse(
+ const ConformanceResponse& response,
+ const ConformanceRequestSetting& setting, Message* test_message) {
+ const ConformanceRequest& request = setting.GetRequest();
+ WireFormat requested_output = request.requested_output_format();
+ const string& test_name = setting.GetTestName();
+ ConformanceLevel level = setting.GetLevel();
+
+ switch (response.result_case()) {
+ case ConformanceResponse::kProtobufPayload: {
+ if (requested_output != conformance::PROTOBUF) {
+ ReportFailure(
+ test_name, level, request, response,
+ StrCat("Test was asked for ", WireFormatToString(requested_output),
+ " output but provided PROTOBUF instead.")
+ .c_str());
+ return false;
+ }
+
+ if (!test_message->ParseFromString(response.protobuf_payload())) {
+ ReportFailure(test_name, level, request, response,
+ "Protobuf output we received from test was unparseable.");
+ return false;
+ }
+
+ break;
+ }
+
+ case ConformanceResponse::kTextPayload: {
+ if (requested_output != conformance::TEXT_FORMAT) {
+ ReportFailure(
+ test_name, level, request, response,
+ StrCat("Test was asked for ", WireFormatToString(requested_output),
+ " output but provided TEXT_FORMAT instead.")
+ .c_str());
+ return false;
+ }
+
+ if (!ParseTextFormatResponse(response, test_message)) {
+ ReportFailure(
+ test_name, level, request, response,
+ "TEXT_FORMAT output we received from test was unparseable.");
+ return false;
+ }
+
+ break;
+ }
+
+ default:
+ GOOGLE_LOG(FATAL) << test_name
+ << ": unknown payload type: " << response.result_case();
+ }
+
+ return true;
+}
+
+void TextFormatConformanceTestSuite::ExpectParseFailure(const string& test_name,
+ ConformanceLevel level,
+ const string& input) {
+ TestAllTypesProto3 prototype;
+ // We don't expect output, but if the program erroneously accepts the protobuf
+ // we let it send its response as this. We must not leave it unspecified.
+ ConformanceRequestSetting setting(
+ level, conformance::TEXT_FORMAT, conformance::TEXT_FORMAT,
+ conformance::TEXT_FORMAT_TEST, prototype, test_name, input);
+ const ConformanceRequest& request = setting.GetRequest();
+ ConformanceResponse response;
+ string effective_test_name = StrCat(setting.ConformanceLevelToString(level),
+ ".Proto3.TextFormatInput.", test_name);
+
+ RunTest(effective_test_name, request, &response);
+ if (response.result_case() == ConformanceResponse::kParseError) {
+ ReportSuccess(effective_test_name);
+ } else if (response.result_case() == ConformanceResponse::kSkipped) {
+ ReportSkip(effective_test_name, request, response);
+ } else {
+ ReportFailure(effective_test_name, level, request, response,
+ "Should have failed to parse, but didn't.");
+ }
+}
+
+void TextFormatConformanceTestSuite::RunValidTextFormatTest(
+ const string& test_name, ConformanceLevel level, const string& input_text) {
+ TestAllTypesProto3 prototype;
+ RunValidTextFormatTestWithMessage(test_name, level, input_text, prototype);
+}
+
+void TextFormatConformanceTestSuite::RunValidTextFormatTestProto2(
+ const string& test_name, ConformanceLevel level, const string& input_text) {
+ TestAllTypesProto2 prototype;
+ RunValidTextFormatTestWithMessage(test_name, level, input_text, prototype);
+}
+
+void TextFormatConformanceTestSuite::RunValidTextFormatTestWithMessage(
+ const string& test_name, ConformanceLevel level, const string& input_text,
+ const Message& prototype) {
+ ConformanceRequestSetting setting1(
+ level, conformance::TEXT_FORMAT, conformance::PROTOBUF,
+ conformance::TEXT_FORMAT_TEST, prototype, test_name, input_text);
+ RunValidInputTest(setting1, input_text);
+ ConformanceRequestSetting setting2(
+ level, conformance::TEXT_FORMAT, conformance::TEXT_FORMAT,
+ conformance::TEXT_FORMAT_TEST, prototype, test_name, input_text);
+ RunValidInputTest(setting2, input_text);
+}
+
+void TextFormatConformanceTestSuite::RunSuiteImpl() {
+ RunValidTextFormatTest("HelloWorld", REQUIRED,
+ "optional_string: 'Hello, World!'");
+ // Integer fields.
+ RunValidTextFormatTest("Int32FieldMaxValue", REQUIRED,
+ "optional_int32: 2147483647");
+ RunValidTextFormatTest("Int32FieldMinValue", REQUIRED,
+ "optional_int32: -2147483648");
+ RunValidTextFormatTest("Uint32FieldMaxValue", REQUIRED,
+ "optional_uint32: 4294967295");
+ RunValidTextFormatTest("Int64FieldMaxValue", REQUIRED,
+ "optional_int64: 9223372036854775807");
+ RunValidTextFormatTest("Int64FieldMinValue", REQUIRED,
+ "optional_int64: -9223372036854775808");
+ RunValidTextFormatTest("Uint64FieldMaxValue", REQUIRED,
+ "optional_uint64: 18446744073709551615");
+
+ // Parsers reject out-of-bound integer values.
+ ExpectParseFailure("Int32FieldTooLarge", REQUIRED,
+ "optional_int32: 2147483648");
+ ExpectParseFailure("Int32FieldTooSmall", REQUIRED,
+ "optional_int32: -2147483649");
+ ExpectParseFailure("Uint32FieldTooLarge", REQUIRED,
+ "optional_uint32: 4294967296");
+ ExpectParseFailure("Int64FieldTooLarge", REQUIRED,
+ "optional_int64: 9223372036854775808");
+ ExpectParseFailure("Int64FieldTooSmall", REQUIRED,
+ "optional_int64: -9223372036854775809");
+ ExpectParseFailure("Uint64FieldTooLarge", REQUIRED,
+ "optional_uint64: 18446744073709551616");
+
+ // Floating point fields
+ RunValidTextFormatTest("FloatField", REQUIRED,
+ "optional_float: 3.192837");
+ RunValidTextFormatTest("FloatFieldWithVeryPreciseNumber", REQUIRED,
+ "optional_float: 3.123456789123456789");
+ RunValidTextFormatTest("FloatFieldMaxValue", REQUIRED,
+ "optional_float: 3.40282e+38");
+ RunValidTextFormatTest("FloatFieldMinValue", REQUIRED,
+ "optional_float: 1.17549e-38");
+ RunValidTextFormatTest("FloatFieldNaNValue", REQUIRED,
+ "optional_float: NaN");
+ RunValidTextFormatTest("FloatFieldPosInfValue", REQUIRED,
+ "optional_float: inf");
+ RunValidTextFormatTest("FloatFieldNegInfValue", REQUIRED,
+ "optional_float: -inf");
+ RunValidTextFormatTest("FloatFieldWithInt32Max", REQUIRED,
+ "optional_float: 4294967296");
+ RunValidTextFormatTest("FloatFieldLargerThanInt64", REQUIRED,
+ "optional_float: 9223372036854775808");
+
+ ExpectParseFailure("FloatFieldTooLarge", REQUIRED,
+ "optional_int32: 3.4028235e+39");
+ ExpectParseFailure("FloatFieldTooSmall", REQUIRED,
+ "optional_int32: 1.17549e-39");
+
+ // Group fields
+ RunValidTextFormatTestProto2("GroupFieldNoColon", REQUIRED,
+ "Data { group_int32: 1 }");
+ RunValidTextFormatTestProto2("GroupFieldWithColon", REQUIRED,
+ "Data: { group_int32: 1 }");
+ RunValidTextFormatTestProto2("GroupFieldEmpty", REQUIRED,
+ "Data {}");
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/conformance/text_format_conformance_suite.h b/conformance/text_format_conformance_suite.h
new file mode 100644
index 0000000..661d45e
--- /dev/null
+++ b/conformance/text_format_conformance_suite.h
@@ -0,0 +1,66 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef TEXT_FORMAT_CONFORMANCE_SUITE_H_
+#define TEXT_FORMAT_CONFORMANCE_SUITE_H_
+
+#include "conformance_test.h"
+
+namespace google {
+namespace protobuf {
+
+class TextFormatConformanceTestSuite : public ConformanceTestSuite {
+ public:
+ TextFormatConformanceTestSuite();
+
+ private:
+ void RunSuiteImpl();
+ void RunValidTextFormatTest(const string& test_name, ConformanceLevel level,
+ const string& input);
+ void RunValidTextFormatTestProto2(const string& test_name,
+ ConformanceLevel level,
+ const string& input);
+ void RunValidTextFormatTestWithMessage(const string& test_name,
+ ConformanceLevel level,
+ const string& input_text,
+ const Message& prototype);
+ void ExpectParseFailure(const string& test_name, ConformanceLevel level,
+ const string& input);
+ bool ParseTextFormatResponse(const conformance::ConformanceResponse& response,
+ Message* test_message);
+ bool ParseResponse(const conformance::ConformanceResponse& response,
+ const ConformanceRequestSetting& setting,
+ Message* test_message) override;
+};
+
+} // namespace protobuf
+} // namespace google
+
+#endif // TEXT_FORMAT_CONFORMANCE_SUITE_H_
diff --git a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java
index ec48796..6cece05 100644
--- a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java
+++ b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java
@@ -3006,7 +3006,39 @@
throw InvalidProtocolBufferException.truncatedMessage();
}
- if (refillCallback != null) {
+ int totalSkipped = 0;
+ if (refillCallback == null) {
+ // Skipping more bytes than are in the buffer. First skip what we have.
+ totalBytesRetired += pos;
+ totalSkipped = bufferSize - pos;
+ bufferSize = 0;
+ pos = 0;
+
+ try {
+ while (totalSkipped < size) {
+ int toSkip = size - totalSkipped;
+ long skipped = input.skip(toSkip);
+ if (skipped < 0 || skipped > toSkip) {
+ throw new IllegalStateException(
+ input.getClass()
+ + "#skip returned invalid result: "
+ + skipped
+ + "\nThe InputStream implementation is buggy.");
+ } else if (skipped == 0) {
+ // The API contract of skip() permits an inputstream to skip zero bytes for any reason
+ // it wants. In particular, ByteArrayInputStream will just return zero over and over
+ // when it's at the end of its input. In order to actually confirm that we've hit the
+ // end of input, we need to issue a read call via the other path.
+ break;
+ }
+ totalSkipped += (int) skipped;
+ }
+ } finally {
+ totalBytesRetired += totalSkipped;
+ recomputeBufferSizeAfterLimit();
+ }
+ }
+ if (totalSkipped < size) {
// Skipping more bytes than are in the buffer. First skip what we have.
int tempPos = bufferSize - pos;
pos = bufferSize;
@@ -3021,30 +3053,6 @@
}
pos = size - tempPos;
- } else {
- // Skipping more bytes than are in the buffer. First skip what we have.
- totalBytesRetired += pos;
- int totalSkipped = bufferSize - pos;
- bufferSize = 0;
- pos = 0;
-
- try {
- while (totalSkipped < size) {
- int toSkip = size - totalSkipped;
- long skipped = input.skip(toSkip);
- if (skipped < 0 || skipped > toSkip) {
- throw new IllegalStateException(
- input.getClass()
- + "#skip returned invalid result: "
- + skipped
- + "\nThe InputStream implementation is buggy.");
- }
- totalSkipped += (int) skipped;
- }
- } finally {
- totalBytesRetired += totalSkipped;
- recomputeBufferSizeAfterLimit();
- }
}
}
}
diff --git a/java/core/src/main/java/com/google/protobuf/Descriptors.java b/java/core/src/main/java/com/google/protobuf/Descriptors.java
index 6f8696e..8b7e1cc 100644
--- a/java/core/src/main/java/com/google/protobuf/Descriptors.java
+++ b/java/core/src/main/java/com/google/protobuf/Descriptors.java
@@ -185,8 +185,9 @@
if (name.indexOf('.') != -1) {
return null;
}
- if (getPackage().length() > 0) {
- name = getPackage() + '.' + name;
+ final String packageName = getPackage();
+ if (!packageName.isEmpty()) {
+ name = packageName + '.' + name;
}
final GenericDescriptor result = pool.findSymbol(name);
if (result != null && result instanceof Descriptor && result.getFile() == this) {
@@ -208,8 +209,9 @@
if (name.indexOf('.') != -1) {
return null;
}
- if (getPackage().length() > 0) {
- name = getPackage() + '.' + name;
+ final String packageName = getPackage();
+ if (!packageName.isEmpty()) {
+ name = packageName + '.' + name;
}
final GenericDescriptor result = pool.findSymbol(name);
if (result != null && result instanceof EnumDescriptor && result.getFile() == this) {
@@ -231,8 +233,9 @@
if (name.indexOf('.') != -1) {
return null;
}
- if (getPackage().length() > 0) {
- name = getPackage() + '.' + name;
+ final String packageName = getPackage();
+ if (!packageName.isEmpty()) {
+ name = packageName + '.' + name;
}
final GenericDescriptor result = pool.findSymbol(name);
if (result != null && result instanceof ServiceDescriptor && result.getFile() == this) {
@@ -252,8 +255,9 @@
if (name.indexOf('.') != -1) {
return null;
}
- if (getPackage().length() > 0) {
- name = getPackage() + '.' + name;
+ final String packageName = getPackage();
+ if (!packageName.isEmpty()) {
+ name = packageName + '.' + name;
}
final GenericDescriptor result = pool.findSymbol(name);
if (result != null && result instanceof FieldDescriptor && result.getFile() == this) {
@@ -1223,14 +1227,20 @@
// This method should match exactly with the ToJsonName() function in C++
// descriptor.cc.
private static String fieldNameToJsonName(String name) {
- StringBuilder result = new StringBuilder(name.length());
+ final int length = name.length();
+ StringBuilder result = new StringBuilder(length);
boolean isNextUpperCase = false;
- for (int i = 0; i < name.length(); i++) {
+ for (int i = 0; i < length; i++) {
char ch = name.charAt(i);
if (ch == '_') {
isNextUpperCase = true;
} else if (isNextUpperCase) {
- result.append(Character.toUpperCase(ch));
+ // This closely matches the logic for ASCII characters in:
+ // http://google3/google/protobuf/descriptor.cc?l=249-251&rcl=228891689
+ if ('a' <= ch && ch <= 'z') {
+ ch = (char) (ch - 'a' + 'A');
+ }
+ result.append(ch);
isNextUpperCase = false;
} else {
result.append(ch);
@@ -1787,7 +1797,6 @@
file.pool.addEnumValueByNumber(this);
}
- private Integer number;
// Create an unknown enum value.
private EnumValueDescriptor(
final FileDescriptor file, final EnumDescriptor parent, final Integer number) {
@@ -1799,7 +1808,6 @@
this.file = file;
this.type = parent;
this.fullName = parent.getFullName() + '.' + proto.getName();
- this.number = number;
// Don't add this descriptor into pool.
}
@@ -2029,11 +2037,14 @@
final FileDescriptor file, final Descriptor parent, final String name) {
if (parent != null) {
return parent.getFullName() + '.' + name;
- } else if (file.getPackage().length() > 0) {
- return file.getPackage() + '.' + name;
- } else {
- return name;
}
+
+ final String packageName = file.getPackage();
+ if (!packageName.isEmpty()) {
+ return packageName + '.' + name;
+ }
+
+ return name;
}
// =================================================================
@@ -2322,13 +2333,13 @@
validateSymbolName(descriptor);
final String fullName = descriptor.getFullName();
- final int dotpos = fullName.lastIndexOf('.');
final GenericDescriptor old = descriptorsByName.put(fullName, descriptor);
if (old != null) {
descriptorsByName.put(fullName, old);
if (descriptor.getFile() == old.getFile()) {
+ final int dotpos = fullName.lastIndexOf('.');
if (dotpos == -1) {
throw new DescriptorValidationException(
descriptor, '\"' + fullName + "\" is already defined.");
@@ -2494,27 +2505,22 @@
final String name = descriptor.getName();
if (name.length() == 0) {
throw new DescriptorValidationException(descriptor, "Missing name.");
- } else {
- boolean valid = true;
- for (int i = 0; i < name.length(); i++) {
- final char c = name.charAt(i);
- // Non-ASCII characters are not valid in protobuf identifiers, even
- // if they are letters or digits.
- if (c >= 128) {
- valid = false;
- }
- // First character must be letter or _. Subsequent characters may
- // be letters, numbers, or digits.
- if (Character.isLetter(c) || c == '_' || (Character.isDigit(c) && i > 0)) {
- // Valid
- } else {
- valid = false;
- }
+ }
+
+ // Non-ASCII characters are not valid in protobuf identifiers, even
+ // if they are letters or digits.
+ // The first character must be a letter or '_'.
+ // Subsequent characters may be letters, numbers, or digits.
+ for (int i = 0; i < name.length(); i++) {
+ final char c = name.charAt(i);
+ if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')
+ || (c == '_')
+ || ('0' <= c && c <= '9' && i > 0)) {
+ // Valid
+ continue;
}
- if (!valid) {
- throw new DescriptorValidationException(
- descriptor, '\"' + name + "\" is not a valid identifier.");
- }
+ throw new DescriptorValidationException(
+ descriptor, '\"' + name + "\" is not a valid identifier.");
}
}
}
diff --git a/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java b/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java
index 998f4d5..9c5d6da 100644
--- a/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java
+++ b/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java
@@ -1186,4 +1186,13 @@
}
}
}
+
+ public void testSkipPastEndOfByteArrayInput() throws Exception {
+ try {
+ CodedInputStream.newInstance(new ByteArrayInputStream(new byte[100])).skipRawBytes(101);
+ fail();
+ } catch (InvalidProtocolBufferException e) {
+ // Expected
+ }
+ }
}
diff --git a/java/core/src/test/java/com/google/protobuf/ParseExceptionsTest.java b/java/core/src/test/java/com/google/protobuf/ParseExceptionsTest.java
index 20b9380..4e63ee7 100644
--- a/java/core/src/test/java/com/google/protobuf/ParseExceptionsTest.java
+++ b/java/core/src/test/java/com/google/protobuf/ParseExceptionsTest.java
@@ -217,6 +217,23 @@
}
@Test
+ public void messageBuilder_mergeDelimitedFrom_InputStream_malformed() throws Exception {
+ byte[] body = new byte[80];
+ CodedOutputStream cos = CodedOutputStream.newInstance(body);
+ cos.writeRawVarint32(90); // Greater than bytes in stream
+ cos.writeTag(DescriptorProto.ENUM_TYPE_FIELD_NUMBER, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ cos.writeRawVarint32(98); // Nested message with size larger than parent
+ cos.writeTag(1000, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ cos.writeRawVarint32(100); // Unknown field with size larger than parent
+ ByteArrayInputStream bais = new ByteArrayInputStream(body);
+ try {
+ DescriptorProto.parseDelimitedFrom(bais);
+ fail();
+ } catch (InvalidProtocolBufferException expected) {
+ }
+ }
+
+ @Test
public void messageBuilder_mergeDelimitedFrom_InputStreamAndExtensionRegistry() {
setupDelimited();
verifyExceptions(
diff --git a/js/binary/writer.js b/js/binary/writer.js
index 287d29c..ae1c29b 100644
--- a/js/binary/writer.js
+++ b/js/binary/writer.js
@@ -800,6 +800,38 @@
/**
+ * Writes a message set extension to the buffer.
+ * @param {number} field The field number for the extension.
+ * @param {?MessageType} value The extension message object to write. Note that
+ * message set can only have extensions with type of optional message.
+ * @param {function(!MessageTypeNonNull, !jspb.BinaryWriter)} writerCallback
+ * Will be invoked with the value to write and the writer to write it with.
+ * @template MessageType
+ * Use go/closure-ttl to declare a non-nullable version of MessageType. Replace
+ * the null in blah|null with none. This is necessary because the compiler will
+ * infer MessageType to be nullable if the value parameter is nullable.
+ * @template MessageTypeNonNull :=
+ * cond(isUnknown(MessageType), unknown(),
+ * mapunion(MessageType, (X) =>
+ * cond(eq(X, 'null'), none(), X)))
+ * =:
+ */
+jspb.BinaryWriter.prototype.writeMessageSet = function(
+ field, value, writerCallback) {
+ if (value == null) return;
+ // The wire format for a message set is defined by
+ // google3/net/proto/message_set.proto
+ this.writeFieldHeader_(1, jspb.BinaryConstants.WireType.START_GROUP);
+ this.writeFieldHeader_(2, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeSignedVarint32(field);
+ var bookmark = this.beginDelimited_(3);
+ writerCallback(value, this);
+ this.endDelimited_(bookmark);
+ this.writeFieldHeader_(1, jspb.BinaryConstants.WireType.END_GROUP);
+};
+
+
+/**
* Writes a group message to the buffer.
*
* @param {number} field The field number.
diff --git a/js/message.js b/js/message.js
index 1ca9fac..eb54678 100644
--- a/js/message.js
+++ b/js/message.js
@@ -183,9 +183,6 @@
* calling fromObject. Enabling this might disable the JSCompiler's ability
* to dead code eliminate fields used in protocol buffers that are never
* used in an application.
- * NOTE: By default no protos actually have a fromObject method. You need to
- * add the jspb.generate_from_object options to the proto definition to
- * activate the feature.
* By default this is enabled for test code only.
*/
goog.define('jspb.Message.GENERATE_FROM_OBJECT', !goog.DISALLOW_TEST_ONLY_CODE);
@@ -703,20 +700,7 @@
* @protected
*/
jspb.Message.getRepeatedField = function(msg, fieldNumber) {
- if (fieldNumber < msg.pivot_) {
- var index = jspb.Message.getIndex_(msg, fieldNumber);
- var val = msg.array[index];
- if (val === jspb.Message.EMPTY_LIST_SENTINEL_) {
- return msg.array[index] = [];
- }
- return val;
- }
-
- var val = msg.extensionObject_[fieldNumber];
- if (val === jspb.Message.EMPTY_LIST_SENTINEL_) {
- return msg.extensionObject_[fieldNumber] = [];
- }
- return val;
+ return /** @type {!Array} */ (jspb.Message.getField(msg, fieldNumber));
};
diff --git a/js/test.proto b/js/test.proto
index bc1a9b6..1c0d255 100644
--- a/js/test.proto
+++ b/js/test.proto
@@ -106,6 +106,13 @@
}
}
+message MineField {
+ // document.cookie is a banned property in a couple of conformance check
+ // configs at Google. Verify that having a field called cookie doesn't confuse
+ // the compiler and break the build.
+ optional string cookie = 1;
+}
+
message IsExtension {
extend HasExtensions {
optional IsExtension ext_field = 100;
@@ -261,7 +268,6 @@
}
message TestMapFieldsNoBinary {
-
map<string, string> map_string_string = 1;
map<string, int32> map_string_int32 = 2;
map<string, int64> map_string_int64 = 3;
@@ -285,7 +291,6 @@
}
message MapValueMessageNoBinary {
-
optional int32 foo = 1;
}
diff --git a/python/google/protobuf/internal/containers.py b/python/google/protobuf/internal/containers.py
index b82936b..9b968e7 100755
--- a/python/google/protobuf/internal/containers.py
+++ b/python/google/protobuf/internal/containers.py
@@ -230,6 +230,8 @@
kwargs['cmp'] = kwargs.pop('sort_function')
self._values.sort(*args, **kwargs)
+collections_abc.MutableSequence.register(BaseContainer)
+
class RepeatedScalarFieldContainer(BaseContainer):
@@ -341,8 +343,6 @@
# We are presumably comparing against some other sequence type.
return other == self._values
-collections_abc.MutableSequence.register(BaseContainer)
-
class RepeatedCompositeFieldContainer(BaseContainer):
@@ -380,6 +380,24 @@
self._message_listener.Modified()
return new_element
+ def append(self, value):
+ """Appends one element by copying the message."""
+ new_element = self._message_descriptor._concrete_class()
+ new_element._SetListener(self._message_listener)
+ new_element.CopyFrom(value)
+ self._values.append(new_element)
+ if not self._message_listener.dirty:
+ self._message_listener.Modified()
+
+ def insert(self, key, value):
+ """Inserts the item at the specified position by copying."""
+ new_element = self._message_descriptor._concrete_class()
+ new_element._SetListener(self._message_listener)
+ new_element.CopyFrom(value)
+ self._values.insert(key, new_element)
+ if not self._message_listener.dirty:
+ self._message_listener.Modified()
+
def extend(self, elem_seq):
"""Extends by appending the given sequence of elements of the same type
as this one, copying each individual message.
diff --git a/python/google/protobuf/internal/extension_dict.py b/python/google/protobuf/internal/extension_dict.py
new file mode 100644
index 0000000..4a1399d
--- /dev/null
+++ b/python/google/protobuf/internal/extension_dict.py
@@ -0,0 +1,185 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Contains _ExtensionDict class to represent extensions.
+"""
+
+from google.protobuf.internal import type_checkers
+from google.protobuf.descriptor import FieldDescriptor
+
+
+def _VerifyExtensionHandle(message, extension_handle):
+ """Verify that the given extension handle is valid."""
+
+ if not isinstance(extension_handle, FieldDescriptor):
+ raise KeyError('HasExtension() expects an extension handle, got: %s' %
+ extension_handle)
+
+ if not extension_handle.is_extension:
+ raise KeyError('"%s" is not an extension.' % extension_handle.full_name)
+
+ if not extension_handle.containing_type:
+ raise KeyError('"%s" is missing a containing_type.'
+ % extension_handle.full_name)
+
+ if extension_handle.containing_type is not message.DESCRIPTOR:
+ raise KeyError('Extension "%s" extends message type "%s", but this '
+ 'message is of type "%s".' %
+ (extension_handle.full_name,
+ extension_handle.containing_type.full_name,
+ message.DESCRIPTOR.full_name))
+
+
+# TODO(robinson): Unify error handling of "unknown extension" crap.
+# TODO(robinson): Support iteritems()-style iteration over all
+# extensions with the "has" bits turned on?
+class _ExtensionDict(object):
+
+ """Dict-like container for Extension fields on proto instances.
+
+ Note that in all cases we expect extension handles to be
+ FieldDescriptors.
+ """
+
+ def __init__(self, extended_message):
+ """
+ Args:
+ extended_message: Message instance for which we are the Extensions dict.
+ """
+ self._extended_message = extended_message
+
+ def __getitem__(self, extension_handle):
+ """Returns the current value of the given extension handle."""
+
+ _VerifyExtensionHandle(self._extended_message, extension_handle)
+
+ result = self._extended_message._fields.get(extension_handle)
+ if result is not None:
+ return result
+
+ if extension_handle.label == FieldDescriptor.LABEL_REPEATED:
+ result = extension_handle._default_constructor(self._extended_message)
+ elif extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE:
+ assert getattr(extension_handle.message_type, '_concrete_class', None), (
+ 'Uninitialized concrete class found for field %r (message type %r)'
+ % (extension_handle.full_name,
+ extension_handle.message_type.full_name))
+ result = extension_handle.message_type._concrete_class()
+ try:
+ result._SetListener(self._extended_message._listener_for_children)
+ except ReferenceError:
+ pass
+ else:
+ # Singular scalar -- just return the default without inserting into the
+ # dict.
+ return extension_handle.default_value
+
+ # Atomically check if another thread has preempted us and, if not, swap
+ # in the new object we just created. If someone has preempted us, we
+ # take that object and discard ours.
+ # WARNING: We are relying on setdefault() being atomic. This is true
+ # in CPython but we haven't investigated others. This warning appears
+ # in several other locations in this file.
+ result = self._extended_message._fields.setdefault(
+ extension_handle, result)
+
+ return result
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return False
+
+ my_fields = self._extended_message.ListFields()
+ other_fields = other._extended_message.ListFields()
+
+ # Get rid of non-extension fields.
+ my_fields = [field for field in my_fields if field.is_extension]
+ other_fields = [field for field in other_fields if field.is_extension]
+
+ return my_fields == other_fields
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __len__(self):
+ fields = self._extended_message.ListFields()
+ # Get rid of non-extension fields.
+ extension_fields = [field for field in fields if field[0].is_extension]
+ return len(extension_fields)
+
+ def __hash__(self):
+ raise TypeError('unhashable object')
+
+ # Note that this is only meaningful for non-repeated, scalar extension
+ # fields. Note also that we may have to call _Modified() when we do
+ # successfully set a field this way, to set any necssary "has" bits in the
+ # ancestors of the extended message.
+ def __setitem__(self, extension_handle, value):
+ """If extension_handle specifies a non-repeated, scalar extension
+ field, sets the value of that field.
+ """
+
+ _VerifyExtensionHandle(self._extended_message, extension_handle)
+
+ if (extension_handle.label == FieldDescriptor.LABEL_REPEATED or
+ extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE):
+ raise TypeError(
+ 'Cannot assign to extension "%s" because it is a repeated or '
+ 'composite type.' % extension_handle.full_name)
+
+ # It's slightly wasteful to lookup the type checker each time,
+ # but we expect this to be a vanishingly uncommon case anyway.
+ type_checker = type_checkers.GetTypeChecker(extension_handle)
+ # pylint: disable=protected-access
+ self._extended_message._fields[extension_handle] = (
+ type_checker.CheckValue(value))
+ self._extended_message._Modified()
+
+ def _FindExtensionByName(self, name):
+ """Tries to find a known extension with the specified name.
+
+ Args:
+ name: Extension full name.
+
+ Returns:
+ Extension field descriptor.
+ """
+ return self._extended_message._extensions_by_name.get(name, None)
+
+ def _FindExtensionByNumber(self, number):
+ """Tries to find a known extension with the field number.
+
+ Args:
+ number: Extension field number.
+
+ Returns:
+ Extension field descriptor.
+ """
+ return self._extended_message._extensions_by_number.get(number, None)
diff --git a/python/google/protobuf/internal/json_format_test.py b/python/google/protobuf/internal/json_format_test.py
index 0f5b630..2695635 100644
--- a/python/google/protobuf/internal/json_format_test.py
+++ b/python/google/protobuf/internal/json_format_test.py
@@ -52,7 +52,6 @@
from google.protobuf import any_test_pb2
from google.protobuf import unittest_mset_pb2
from google.protobuf import unittest_pb2
-from google.protobuf.internal import well_known_types
from google.protobuf import descriptor_pool
from google.protobuf import json_format
from google.protobuf.util import json_format_proto3_pb2
@@ -481,6 +480,14 @@
parsed_message = json_format_proto3_pb2.TestFieldMask()
self.CheckParseBack(message, parsed_message)
+ message.value.Clear()
+ self.assertEqual(
+ json_format.MessageToJson(message, True),
+ '{\n'
+ ' "value": ""\n'
+ '}')
+ self.CheckParseBack(message, parsed_message)
+
def testWrapperMessage(self):
message = json_format_proto3_pb2.TestWrapper()
message.bool_value.value = False
@@ -922,17 +929,18 @@
text = '{"value": "10000-01-01T00:00:00.00Z"}'
self.assertRaisesRegexp(
json_format.ParseError,
+ 'Failed to parse value field: '
'time data \'10000-01-01T00:00:00\' does not match'
' format \'%Y-%m-%dT%H:%M:%S\'.',
json_format.Parse, text, message)
text = '{"value": "1970-01-01T00:00:00.0123456789012Z"}'
self.assertRaisesRegexp(
- well_known_types.ParseError,
+ json_format.ParseError,
'nanos 0123456789012 more than 9 fractional digits.',
json_format.Parse, text, message)
text = '{"value": "1972-01-01T01:00:00.01+08"}'
self.assertRaisesRegexp(
- well_known_types.ParseError,
+ json_format.ParseError,
(r'Invalid timezone offset value: \+08.'),
json_format.Parse, text, message)
# Time smaller than minimum time.
diff --git a/python/google/protobuf/internal/message_factory_test.py b/python/google/protobuf/internal/message_factory_test.py
index b97e3f6..5be65c7 100644
--- a/python/google/protobuf/internal/message_factory_test.py
+++ b/python/google/protobuf/internal/message_factory_test.py
@@ -136,13 +136,14 @@
'google.protobuf.python.internal.Factory2Message.one_more_field')
ext2 = msg1.Extensions._FindExtensionByName(
'google.protobuf.python.internal.another_field')
+ self.assertEqual(0, len(msg1.Extensions))
msg1.Extensions[ext1] = 'test1'
msg1.Extensions[ext2] = 'test2'
self.assertEqual('test1', msg1.Extensions[ext1])
self.assertEqual('test2', msg1.Extensions[ext2])
self.assertEqual(None,
msg1.Extensions._FindExtensionByNumber(12321))
- self.assertRaises(TypeError, len, msg1.Extensions)
+ self.assertEqual(2, len(msg1.Extensions))
if api_implementation.Type() == 'cpp':
self.assertRaises(TypeError,
msg1.Extensions._FindExtensionByName, 0)
diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py
index 137420d..80a65e3 100755
--- a/python/google/protobuf/internal/message_test.py
+++ b/python/google/protobuf/internal/message_test.py
@@ -411,6 +411,58 @@
empty.ParseFromString(populated.SerializeToString())
self.assertEqual(str(empty), '')
+ def testAppendRepeatedCompositeField(self, message_module):
+ msg = message_module.TestAllTypes()
+ msg.repeated_nested_message.append(
+ message_module.TestAllTypes.NestedMessage(bb=1))
+ nested = message_module.TestAllTypes.NestedMessage(bb=2)
+ msg.repeated_nested_message.append(nested)
+ try:
+ msg.repeated_nested_message.append(1)
+ except TypeError:
+ pass
+ self.assertEqual(2, len(msg.repeated_nested_message))
+ self.assertEqual([1, 2],
+ [m.bb for m in msg.repeated_nested_message])
+
+ def testInsertRepeatedCompositeField(self, message_module):
+ msg = message_module.TestAllTypes()
+ msg.repeated_nested_message.insert(
+ -1, message_module.TestAllTypes.NestedMessage(bb=1))
+ sub_msg = msg.repeated_nested_message[0]
+ msg.repeated_nested_message.insert(
+ 0, message_module.TestAllTypes.NestedMessage(bb=2))
+ msg.repeated_nested_message.insert(
+ 99, message_module.TestAllTypes.NestedMessage(bb=3))
+ msg.repeated_nested_message.insert(
+ -2, message_module.TestAllTypes.NestedMessage(bb=-1))
+ msg.repeated_nested_message.insert(
+ -1000, message_module.TestAllTypes.NestedMessage(bb=-1000))
+ try:
+ msg.repeated_nested_message.insert(1, 999)
+ except TypeError:
+ pass
+ self.assertEqual(5, len(msg.repeated_nested_message))
+ self.assertEqual([-1000, 2, -1, 1, 3],
+ [m.bb for m in msg.repeated_nested_message])
+ self.assertEqual(str(msg),
+ 'repeated_nested_message {\n'
+ ' bb: -1000\n'
+ '}\n'
+ 'repeated_nested_message {\n'
+ ' bb: 2\n'
+ '}\n'
+ 'repeated_nested_message {\n'
+ ' bb: -1\n'
+ '}\n'
+ 'repeated_nested_message {\n'
+ ' bb: 1\n'
+ '}\n'
+ 'repeated_nested_message {\n'
+ ' bb: 3\n'
+ '}\n')
+ self.assertEqual(sub_msg.bb, 1)
+
def testMergeFromRepeatedField(self, message_module):
msg = message_module.TestAllTypes()
msg.repeated_int32.append(1)
@@ -442,6 +494,30 @@
pass
self.assertEqual(len(msg.repeated_nested_message), 0)
+ def testRepeatedContains(self, message_module):
+ msg = message_module.TestAllTypes()
+ msg.repeated_int32.extend([1, 2, 3])
+ self.assertIn(2, msg.repeated_int32)
+ self.assertNotIn(0, msg.repeated_int32)
+
+ msg.repeated_nested_message.add(bb=1)
+ sub_msg1 = msg.repeated_nested_message[0]
+ sub_msg2 = message_module.TestAllTypes.NestedMessage(bb=2)
+ sub_msg3 = message_module.TestAllTypes.NestedMessage(bb=3)
+ msg.repeated_nested_message.append(sub_msg2)
+ msg.repeated_nested_message.insert(0, sub_msg3)
+ self.assertIn(sub_msg1, msg.repeated_nested_message)
+ self.assertIn(sub_msg2, msg.repeated_nested_message)
+ self.assertIn(sub_msg3, msg.repeated_nested_message)
+
+ def testRepeatedScalarIterable(self, message_module):
+ msg = message_module.TestAllTypes()
+ msg.repeated_int32.extend([1, 2, 3])
+ add = 0
+ for item in msg.repeated_int32:
+ add += item
+ self.assertEqual(add, 6)
+
def testRepeatedNestedFieldIteration(self, message_module):
msg = message_module.TestAllTypes()
msg.repeated_nested_message.add(bb=1)
@@ -1173,6 +1249,27 @@
with self.assertRaises(AttributeError):
m.repeated_int32 = []
+ def testReturningType(self, message_module):
+ m = message_module.TestAllTypes()
+ self.assertEqual(float, type(m.optional_float))
+ self.assertEqual(float, type(m.optional_double))
+ self.assertEqual(bool, type(m.optional_bool))
+ m.optional_float = 1
+ m.optional_double = 1
+ m.optional_bool = 1
+ m.repeated_float.append(1)
+ m.repeated_double.append(1)
+ m.repeated_bool.append(1)
+ m.ParseFromString(m.SerializeToString())
+ self.assertEqual(float, type(m.optional_float))
+ self.assertEqual(float, type(m.optional_double))
+ self.assertEqual('1.0', str(m.optional_double))
+ self.assertEqual(bool, type(m.optional_bool))
+ self.assertEqual(float, type(m.repeated_float[0]))
+ self.assertEqual(float, type(m.repeated_double[0]))
+ self.assertEqual(bool, type(m.repeated_bool[0]))
+ self.assertEqual(True, m.repeated_bool[0])
+
# Class to test proto2-only features (required, extensions, etc.)
class Proto2Test(BaseTestCase):
diff --git a/python/google/protobuf/internal/more_messages.proto b/python/google/protobuf/internal/more_messages.proto
index 2c6ab9e..612f029 100644
--- a/python/google/protobuf/internal/more_messages.proto
+++ b/python/google/protobuf/internal/more_messages.proto
@@ -50,3 +50,262 @@
optional uint64 optional_uint64 = 4;
optional int64 optional_int64 = 2;
}
+
+message LotsNestedMessage {
+ message B0 {}
+ message B1 {}
+ message B2 {}
+ message B3 {}
+ message B4 {}
+ message B5 {}
+ message B6 {}
+ message B7 {}
+ message B8 {}
+ message B9 {}
+ message B10 {}
+ message B11 {}
+ message B12 {}
+ message B13 {}
+ message B14 {}
+ message B15 {}
+ message B16 {}
+ message B17 {}
+ message B18 {}
+ message B19 {}
+ message B20 {}
+ message B21 {}
+ message B22 {}
+ message B23 {}
+ message B24 {}
+ message B25 {}
+ message B26 {}
+ message B27 {}
+ message B28 {}
+ message B29 {}
+ message B30 {}
+ message B31 {}
+ message B32 {}
+ message B33 {}
+ message B34 {}
+ message B35 {}
+ message B36 {}
+ message B37 {}
+ message B38 {}
+ message B39 {}
+ message B40 {}
+ message B41 {}
+ message B42 {}
+ message B43 {}
+ message B44 {}
+ message B45 {}
+ message B46 {}
+ message B47 {}
+ message B48 {}
+ message B49 {}
+ message B50 {}
+ message B51 {}
+ message B52 {}
+ message B53 {}
+ message B54 {}
+ message B55 {}
+ message B56 {}
+ message B57 {}
+ message B58 {}
+ message B59 {}
+ message B60 {}
+ message B61 {}
+ message B62 {}
+ message B63 {}
+ message B64 {}
+ message B65 {}
+ message B66 {}
+ message B67 {}
+ message B68 {}
+ message B69 {}
+ message B70 {}
+ message B71 {}
+ message B72 {}
+ message B73 {}
+ message B74 {}
+ message B75 {}
+ message B76 {}
+ message B77 {}
+ message B78 {}
+ message B79 {}
+ message B80 {}
+ message B81 {}
+ message B82 {}
+ message B83 {}
+ message B84 {}
+ message B85 {}
+ message B86 {}
+ message B87 {}
+ message B88 {}
+ message B89 {}
+ message B90 {}
+ message B91 {}
+ message B92 {}
+ message B93 {}
+ message B94 {}
+ message B95 {}
+ message B96 {}
+ message B97 {}
+ message B98 {}
+ message B99 {}
+ message B100 {}
+ message B101 {}
+ message B102 {}
+ message B103 {}
+ message B104 {}
+ message B105 {}
+ message B106 {}
+ message B107 {}
+ message B108 {}
+ message B109 {}
+ message B110 {}
+ message B111 {}
+ message B112 {}
+ message B113 {}
+ message B114 {}
+ message B115 {}
+ message B116 {}
+ message B117 {}
+ message B118 {}
+ message B119 {}
+ message B120 {}
+ message B121 {}
+ message B122 {}
+ message B123 {}
+ message B124 {}
+ message B125 {}
+ message B126 {}
+ message B127 {}
+ message B128 {}
+ message B129 {}
+ message B130 {}
+ message B131 {}
+ message B132 {}
+ message B133 {}
+ message B134 {}
+ message B135 {}
+ message B136 {}
+ message B137 {}
+ message B138 {}
+ message B139 {}
+ message B140 {}
+ message B141 {}
+ message B142 {}
+ message B143 {}
+ message B144 {}
+ message B145 {}
+ message B146 {}
+ message B147 {}
+ message B148 {}
+ message B149 {}
+ message B150 {}
+ message B151 {}
+ message B152 {}
+ message B153 {}
+ message B154 {}
+ message B155 {}
+ message B156 {}
+ message B157 {}
+ message B158 {}
+ message B159 {}
+ message B160 {}
+ message B161 {}
+ message B162 {}
+ message B163 {}
+ message B164 {}
+ message B165 {}
+ message B166 {}
+ message B167 {}
+ message B168 {}
+ message B169 {}
+ message B170 {}
+ message B171 {}
+ message B172 {}
+ message B173 {}
+ message B174 {}
+ message B175 {}
+ message B176 {}
+ message B177 {}
+ message B178 {}
+ message B179 {}
+ message B180 {}
+ message B181 {}
+ message B182 {}
+ message B183 {}
+ message B184 {}
+ message B185 {}
+ message B186 {}
+ message B187 {}
+ message B188 {}
+ message B189 {}
+ message B190 {}
+ message B191 {}
+ message B192 {}
+ message B193 {}
+ message B194 {}
+ message B195 {}
+ message B196 {}
+ message B197 {}
+ message B198 {}
+ message B199 {}
+ message B200 {}
+ message B201 {}
+ message B202 {}
+ message B203 {}
+ message B204 {}
+ message B205 {}
+ message B206 {}
+ message B207 {}
+ message B208 {}
+ message B209 {}
+ message B210 {}
+ message B211 {}
+ message B212 {}
+ message B213 {}
+ message B214 {}
+ message B215 {}
+ message B216 {}
+ message B217 {}
+ message B218 {}
+ message B219 {}
+ message B220 {}
+ message B221 {}
+ message B222 {}
+ message B223 {}
+ message B224 {}
+ message B225 {}
+ message B226 {}
+ message B227 {}
+ message B228 {}
+ message B229 {}
+ message B230 {}
+ message B231 {}
+ message B232 {}
+ message B233 {}
+ message B234 {}
+ message B235 {}
+ message B236 {}
+ message B237 {}
+ message B238 {}
+ message B239 {}
+ message B240 {}
+ message B241 {}
+ message B242 {}
+ message B243 {}
+ message B244 {}
+ message B245 {}
+ message B246 {}
+ message B247 {}
+ message B248 {}
+ message B249 {}
+ message B250 {}
+ message B251 {}
+ message B252 {}
+ message B253 {}
+ message B254 {}
+ message B255 {}
+}
diff --git a/python/google/protobuf/internal/python_message.py b/python/google/protobuf/internal/python_message.py
index 4b5df99..14cb749 100755
--- a/python/google/protobuf/internal/python_message.py
+++ b/python/google/protobuf/internal/python_message.py
@@ -64,6 +64,7 @@
from google.protobuf.internal import decoder
from google.protobuf.internal import encoder
from google.protobuf.internal import enum_type_wrapper
+from google.protobuf.internal import extension_dict
from google.protobuf.internal import message_listener as message_listener_mod
from google.protobuf.internal import type_checkers
from google.protobuf.internal import well_known_types
@@ -74,7 +75,7 @@
_FieldDescriptor = descriptor_mod.FieldDescriptor
_AnyFullTypeName = 'google.protobuf.Any'
-
+_ExtensionDict = extension_dict._ExtensionDict
class GeneratedProtocolMessageType(type):
@@ -237,28 +238,6 @@
return proto_field_name
-def _VerifyExtensionHandle(message, extension_handle):
- """Verify that the given extension handle is valid."""
-
- if not isinstance(extension_handle, _FieldDescriptor):
- raise KeyError('HasExtension() expects an extension handle, got: %s' %
- extension_handle)
-
- if not extension_handle.is_extension:
- raise KeyError('"%s" is not an extension.' % extension_handle.full_name)
-
- if not extension_handle.containing_type:
- raise KeyError('"%s" is missing a containing_type.'
- % extension_handle.full_name)
-
- if extension_handle.containing_type is not message.DESCRIPTOR:
- raise KeyError('Extension "%s" extends message type "%s", but this '
- 'message is of type "%s".' %
- (extension_handle.full_name,
- extension_handle.containing_type.full_name,
- message.DESCRIPTOR.full_name))
-
-
def _AddSlots(message_descriptor, dictionary):
"""Adds a __slots__ entry to dictionary, containing the names of all valid
attributes for this message type.
@@ -379,8 +358,8 @@
def _AddClassAttributesForNestedExtensions(descriptor, dictionary):
- extension_dict = descriptor.extensions_by_name
- for extension_name, extension_field in extension_dict.items():
+ extensions = descriptor.extensions_by_name
+ for extension_name, extension_field in extensions.items():
assert extension_name not in dictionary
dictionary[extension_name] = extension_field
@@ -784,8 +763,8 @@
def _AddPropertiesForExtensions(descriptor, cls):
"""Adds properties for all fields in this protocol message type."""
- extension_dict = descriptor.extensions_by_name
- for extension_name, extension_field in extension_dict.items():
+ extensions = descriptor.extensions_by_name
+ for extension_name, extension_field in extensions.items():
constant_name = extension_name.upper() + '_FIELD_NUMBER'
setattr(cls, constant_name, extension_field.number)
@@ -922,7 +901,7 @@
def _AddClearExtensionMethod(cls):
"""Helper for _AddMessageMethods()."""
def ClearExtension(self, extension_handle):
- _VerifyExtensionHandle(self, extension_handle)
+ extension_dict._VerifyExtensionHandle(self, extension_handle)
# Similar to ClearField(), above.
if extension_handle in self._fields:
@@ -934,7 +913,7 @@
def _AddHasExtensionMethod(cls):
"""Helper for _AddMessageMethods()."""
def HasExtension(self, extension_handle):
- _VerifyExtensionHandle(self, extension_handle)
+ extension_dict._VerifyExtensionHandle(self, extension_handle)
if extension_handle.label == _FieldDescriptor.LABEL_REPEATED:
raise KeyError('"%s" is repeated.' % extension_handle.full_name)
@@ -1550,126 +1529,3 @@
super(_OneofListener, self).Modified()
except ReferenceError:
pass
-
-
-# TODO(robinson): Move elsewhere? This file is getting pretty ridiculous...
-# TODO(robinson): Unify error handling of "unknown extension" crap.
-# TODO(robinson): Support iteritems()-style iteration over all
-# extensions with the "has" bits turned on?
-class _ExtensionDict(object):
-
- """Dict-like container for supporting an indexable "Extensions"
- field on proto instances.
-
- Note that in all cases we expect extension handles to be
- FieldDescriptors.
- """
-
- def __init__(self, extended_message):
- """extended_message: Message instance for which we are the Extensions dict.
- """
-
- self._extended_message = extended_message
-
- def __getitem__(self, extension_handle):
- """Returns the current value of the given extension handle."""
-
- _VerifyExtensionHandle(self._extended_message, extension_handle)
-
- result = self._extended_message._fields.get(extension_handle)
- if result is not None:
- return result
-
- if extension_handle.label == _FieldDescriptor.LABEL_REPEATED:
- result = extension_handle._default_constructor(self._extended_message)
- elif extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- assert getattr(extension_handle.message_type, '_concrete_class', None), (
- 'Uninitialized concrete class found for field %r (message type %r)'
- % (extension_handle.full_name,
- extension_handle.message_type.full_name))
- result = extension_handle.message_type._concrete_class()
- try:
- result._SetListener(self._extended_message._listener_for_children)
- except ReferenceError:
- pass
- else:
- # Singular scalar -- just return the default without inserting into the
- # dict.
- return extension_handle.default_value
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- result = self._extended_message._fields.setdefault(
- extension_handle, result)
-
- return result
-
- def __eq__(self, other):
- if not isinstance(other, self.__class__):
- return False
-
- my_fields = self._extended_message.ListFields()
- other_fields = other._extended_message.ListFields()
-
- # Get rid of non-extension fields.
- my_fields = [field for field in my_fields if field.is_extension]
- other_fields = [field for field in other_fields if field.is_extension]
-
- return my_fields == other_fields
-
- def __ne__(self, other):
- return not self == other
-
- def __hash__(self):
- raise TypeError('unhashable object')
-
- # Note that this is only meaningful for non-repeated, scalar extension
- # fields. Note also that we may have to call _Modified() when we do
- # successfully set a field this way, to set any necssary "has" bits in the
- # ancestors of the extended message.
- def __setitem__(self, extension_handle, value):
- """If extension_handle specifies a non-repeated, scalar extension
- field, sets the value of that field.
- """
-
- _VerifyExtensionHandle(self._extended_message, extension_handle)
-
- if (extension_handle.label == _FieldDescriptor.LABEL_REPEATED or
- extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE):
- raise TypeError(
- 'Cannot assign to extension "%s" because it is a repeated or '
- 'composite type.' % extension_handle.full_name)
-
- # It's slightly wasteful to lookup the type checker each time,
- # but we expect this to be a vanishingly uncommon case anyway.
- type_checker = type_checkers.GetTypeChecker(extension_handle)
- # pylint: disable=protected-access
- self._extended_message._fields[extension_handle] = (
- type_checker.CheckValue(value))
- self._extended_message._Modified()
-
- def _FindExtensionByName(self, name):
- """Tries to find a known extension with the specified name.
-
- Args:
- name: Extension full name.
-
- Returns:
- Extension field descriptor.
- """
- return self._extended_message._extensions_by_name.get(name, None)
-
- def _FindExtensionByNumber(self, number):
- """Tries to find a known extension with the field number.
-
- Args:
- number: Extension field number.
-
- Returns:
- Extension field descriptor.
- """
- return self._extended_message._extensions_by_number.get(number, None)
diff --git a/python/google/protobuf/internal/type_checkers.py b/python/google/protobuf/internal/type_checkers.py
index 0807e7f..df8306a 100755
--- a/python/google/protobuf/internal/type_checkers.py
+++ b/python/google/protobuf/internal/type_checkers.py
@@ -107,13 +107,18 @@
message = ('%.1024r has type %s, but expected one of: %s' %
(proposed_value, type(proposed_value), self._acceptable_types))
raise TypeError(message)
+ # Some field types(float, double and bool) accept other types, must
+ # convert to the correct type in such cases.
+ if self._acceptable_types:
+ if self._acceptable_types[0] in (bool, float):
+ return self._acceptable_types[0](proposed_value)
return proposed_value
class TypeCheckerWithDefault(TypeChecker):
def __init__(self, default_value, *acceptable_types):
- TypeChecker.__init__(self, acceptable_types)
+ TypeChecker.__init__(self, *acceptable_types)
self._default_value = default_value
def DefaultValue(self):
@@ -232,9 +237,9 @@
_FieldDescriptor.CPPTYPE_UINT32: Uint32ValueChecker(),
_FieldDescriptor.CPPTYPE_UINT64: Uint64ValueChecker(),
_FieldDescriptor.CPPTYPE_DOUBLE: TypeCheckerWithDefault(
- 0.0, numbers.Real),
+ 0.0, float, numbers.Real),
_FieldDescriptor.CPPTYPE_FLOAT: TypeCheckerWithDefault(
- 0.0, numbers.Real),
+ 0.0, float, numbers.Real),
_FieldDescriptor.CPPTYPE_BOOL: TypeCheckerWithDefault(
False, bool, numbers.Integral),
_FieldDescriptor.CPPTYPE_STRING: TypeCheckerWithDefault(b'', bytes),
diff --git a/python/google/protobuf/internal/well_known_types.py b/python/google/protobuf/internal/well_known_types.py
index 92df148..6b4df51 100644
--- a/python/google/protobuf/internal/well_known_types.py
+++ b/python/google/protobuf/internal/well_known_types.py
@@ -58,14 +58,6 @@
_DURATION_SECONDS_MAX = 315576000000
-class Error(Exception):
- """Top-level module error."""
-
-
-class ParseError(Error):
- """Thrown in case of parsing error."""
-
-
class Any(object):
"""Class for Any Message type."""
@@ -136,7 +128,7 @@
Example of accepted format: '1972-01-01T10:00:20.021-05:00'
Raises:
- ParseError: On parsing problems.
+ ValueError: On parsing problems.
"""
timezone_offset = value.find('Z')
if timezone_offset == -1:
@@ -144,7 +136,7 @@
if timezone_offset == -1:
timezone_offset = value.rfind('-')
if timezone_offset == -1:
- raise ParseError(
+ raise ValueError(
'Failed to parse timestamp: missing valid timezone offset.')
time_value = value[0:timezone_offset]
# Parse datetime and nanos.
@@ -159,7 +151,7 @@
td = date_object - datetime(1970, 1, 1)
seconds = td.seconds + td.days * _SECONDS_PER_DAY
if len(nano_value) > 9:
- raise ParseError(
+ raise ValueError(
'Failed to parse Timestamp: nanos {0} more than '
'9 fractional digits.'.format(nano_value))
if nano_value:
@@ -169,13 +161,13 @@
# Parse timezone offsets.
if value[timezone_offset] == 'Z':
if len(value) != timezone_offset + 1:
- raise ParseError('Failed to parse timestamp: invalid trailing'
+ raise ValueError('Failed to parse timestamp: invalid trailing'
' data {0}.'.format(value))
else:
timezone = value[timezone_offset:]
pos = timezone.find(':')
if pos == -1:
- raise ParseError(
+ raise ValueError(
'Invalid timezone offset value: {0}.'.format(timezone))
if timezone[0] == '+':
seconds -= (int(timezone[1:pos])*60+int(timezone[pos+1:]))*60
@@ -289,10 +281,10 @@
precision. For example: "1s", "1.01s", "1.0000001s", "-3.100s
Raises:
- ParseError: On parsing problems.
+ ValueError: On parsing problems.
"""
if len(value) < 1 or value[-1] != 's':
- raise ParseError(
+ raise ValueError(
'Duration must end with letter "s": {0}.'.format(value))
try:
pos = value.find('.')
@@ -308,9 +300,9 @@
_CheckDurationValid(seconds, nanos)
self.seconds = seconds
self.nanos = nanos
- except ValueError:
- raise ParseError(
- 'Couldn\'t parse duration: {0}.'.format(value))
+ except ValueError as e:
+ raise ValueError(
+ 'Couldn\'t parse duration: {0} : {1}.'.format(value, e))
def ToNanoseconds(self):
"""Converts a Duration to nanoseconds."""
@@ -375,15 +367,15 @@
def _CheckDurationValid(seconds, nanos):
if seconds < -_DURATION_SECONDS_MAX or seconds > _DURATION_SECONDS_MAX:
- raise Error(
+ raise ValueError(
'Duration is not valid: Seconds {0} must be in range '
'[-315576000000, 315576000000].'.format(seconds))
if nanos <= -_NANOS_PER_SECOND or nanos >= _NANOS_PER_SECOND:
- raise Error(
+ raise ValueError(
'Duration is not valid: Nanos {0} must be in range '
'[-999999999, 999999999].'.format(nanos))
if (nanos < 0 and seconds > 0) or (nanos > 0 and seconds < 0):
- raise Error(
+ raise ValueError(
'Duration is not valid: Sign mismatch.')
@@ -415,8 +407,9 @@
def FromJsonString(self, value):
"""Converts string to FieldMask according to proto3 JSON spec."""
self.Clear()
- for path in value.split(','):
- self.paths.append(_CamelCaseToSnakeCase(path))
+ if value:
+ for path in value.split(','):
+ self.paths.append(_CamelCaseToSnakeCase(path))
def IsValidForDescriptor(self, message_descriptor):
"""Checks whether the FieldMask is valid for Message Descriptor."""
@@ -509,24 +502,26 @@
after_underscore = False
for c in path_name:
if c.isupper():
- raise Error('Fail to print FieldMask to Json string: Path name '
- '{0} must not contain uppercase letters.'.format(path_name))
+ raise ValueError(
+ 'Fail to print FieldMask to Json string: Path name '
+ '{0} must not contain uppercase letters.'.format(path_name))
if after_underscore:
if c.islower():
result.append(c.upper())
after_underscore = False
else:
- raise Error('Fail to print FieldMask to Json string: The '
- 'character after a "_" must be a lowercase letter '
- 'in path name {0}.'.format(path_name))
+ raise ValueError(
+ 'Fail to print FieldMask to Json string: The '
+ 'character after a "_" must be a lowercase letter '
+ 'in path name {0}.'.format(path_name))
elif c == '_':
after_underscore = True
else:
result += c
if after_underscore:
- raise Error('Fail to print FieldMask to Json string: Trailing "_" '
- 'in path name {0}.'.format(path_name))
+ raise ValueError('Fail to print FieldMask to Json string: Trailing "_" '
+ 'in path name {0}.'.format(path_name))
return ''.join(result)
@@ -535,7 +530,7 @@
result = []
for c in path_name:
if c == '_':
- raise ParseError('Fail to parse FieldMask: Path name '
+ raise ValueError('Fail to parse FieldMask: Path name '
'{0} must not contain "_"s.'.format(path_name))
if c.isupper():
result += '_'
@@ -682,7 +677,7 @@
def _AddFieldPaths(node, prefix, field_mask):
"""Adds the field paths descended from node to field_mask."""
- if not node:
+ if not node and prefix:
field_mask.paths.append(prefix)
return
for name in sorted(node):
diff --git a/python/google/protobuf/internal/well_known_types_test.py b/python/google/protobuf/internal/well_known_types_test.py
index bf304b6..95a7023 100644
--- a/python/google/protobuf/internal/well_known_types_test.py
+++ b/python/google/protobuf/internal/well_known_types_test.py
@@ -294,12 +294,12 @@
def testInvalidTimestamp(self):
message = timestamp_pb2.Timestamp()
self.assertRaisesRegexp(
- well_known_types.ParseError,
+ ValueError,
'Failed to parse timestamp: missing valid timezone offset.',
message.FromJsonString,
'')
self.assertRaisesRegexp(
- well_known_types.ParseError,
+ ValueError,
'Failed to parse timestamp: invalid trailing data '
'1970-01-01T00:00:01Ztrail.',
message.FromJsonString,
@@ -310,12 +310,12 @@
' format \'%Y-%m-%dT%H:%M:%S\'',
message.FromJsonString, '10000-01-01T00:00:00.00Z')
self.assertRaisesRegexp(
- well_known_types.ParseError,
+ ValueError,
'nanos 0123456789012 more than 9 fractional digits.',
message.FromJsonString,
'1970-01-01T00:00:00.0123456789012Z')
self.assertRaisesRegexp(
- well_known_types.ParseError,
+ ValueError,
(r'Invalid timezone offset value: \+08.'),
message.FromJsonString,
'1972-01-01T01:00:00.01+08',)
@@ -333,43 +333,43 @@
def testInvalidDuration(self):
message = duration_pb2.Duration()
self.assertRaisesRegexp(
- well_known_types.ParseError,
+ ValueError,
'Duration must end with letter "s": 1.',
message.FromJsonString, '1')
self.assertRaisesRegexp(
- well_known_types.ParseError,
+ ValueError,
'Couldn\'t parse duration: 1...2s.',
message.FromJsonString, '1...2s')
text = '-315576000001.000000000s'
self.assertRaisesRegexp(
- well_known_types.Error,
+ ValueError,
r'Duration is not valid\: Seconds -315576000001 must be in range'
r' \[-315576000000\, 315576000000\].',
message.FromJsonString, text)
text = '315576000001.000000000s'
self.assertRaisesRegexp(
- well_known_types.Error,
+ ValueError,
r'Duration is not valid\: Seconds 315576000001 must be in range'
r' \[-315576000000\, 315576000000\].',
message.FromJsonString, text)
message.seconds = -315576000001
message.nanos = 0
self.assertRaisesRegexp(
- well_known_types.Error,
+ ValueError,
r'Duration is not valid\: Seconds -315576000001 must be in range'
r' \[-315576000000\, 315576000000\].',
message.ToJsonString)
message.seconds = 0
message.nanos = 999999999 + 1
self.assertRaisesRegexp(
- well_known_types.Error,
+ ValueError,
r'Duration is not valid\: Nanos 1000000000 must be in range'
r' \[-999999999\, 999999999\].',
message.ToJsonString)
message.seconds = -1
message.nanos = 1
self.assertRaisesRegexp(
- well_known_types.Error,
+ ValueError,
r'Duration is not valid\: Sign mismatch.',
message.ToJsonString)
@@ -400,6 +400,7 @@
mask.FromJsonString('')
self.assertEqual('', mask.ToJsonString())
+ self.assertEqual([], mask.paths)
mask.FromJsonString('fooBar')
self.assertEqual(['foo_bar'], mask.paths)
mask.FromJsonString('fooBar,barQuz')
@@ -512,6 +513,8 @@
mask2.FromJsonString('bar,quz')
out_mask.Intersect(mask1, mask2)
self.assertEqual('', out_mask.ToJsonString())
+ self.assertEqual(len(out_mask.paths), 0)
+ self.assertEqual(out_mask.paths, [])
# Overlap with duplicated paths.
mask1.FromJsonString('foo,baz.bb')
mask2.FromJsonString('baz.bb,quz')
@@ -526,6 +529,15 @@
mask2.FromJsonString('foo.bar.baz,quz')
out_mask.Intersect(mask1, mask2)
self.assertEqual('foo.bar.baz', out_mask.ToJsonString())
+ # Intersect '' with ''
+ mask1.Clear()
+ mask2.Clear()
+ mask1.paths.append('')
+ mask2.paths.append('')
+ self.assertEqual(mask1.paths, [''])
+ self.assertEqual('', mask1.ToJsonString())
+ out_mask.Intersect(mask1, mask2)
+ self.assertEqual(out_mask.paths, [])
def testMergeMessageWithoutMapFields(self):
# Test merge one field.
@@ -682,7 +694,7 @@
# No uppercase letter is allowed.
self.assertRaisesRegexp(
- well_known_types.Error,
+ ValueError,
'Fail to print FieldMask to Json string: Path name Foo must '
'not contain uppercase letters.',
well_known_types._SnakeCaseToCamelCase,
@@ -692,19 +704,19 @@
# 2. "_" cannot be followed by a digit.
# 3. "_" cannot appear as the last character.
self.assertRaisesRegexp(
- well_known_types.Error,
+ ValueError,
'Fail to print FieldMask to Json string: The character after a '
'"_" must be a lowercase letter in path name foo__bar.',
well_known_types._SnakeCaseToCamelCase,
'foo__bar')
self.assertRaisesRegexp(
- well_known_types.Error,
+ ValueError,
'Fail to print FieldMask to Json string: The character after a '
'"_" must be a lowercase letter in path name foo_3bar.',
well_known_types._SnakeCaseToCamelCase,
'foo_3bar')
self.assertRaisesRegexp(
- well_known_types.Error,
+ ValueError,
'Fail to print FieldMask to Json string: Trailing "_" in path '
'name foo_bar_.',
well_known_types._SnakeCaseToCamelCase,
@@ -718,7 +730,7 @@
self.assertEqual('foo3_bar',
well_known_types._CamelCaseToSnakeCase('foo3Bar'))
self.assertRaisesRegexp(
- well_known_types.ParseError,
+ ValueError,
'Fail to parse FieldMask: Path name foo_bar must not contain "_"s.',
well_known_types._CamelCaseToSnakeCase,
'foo_bar')
diff --git a/python/google/protobuf/json_format.py b/python/google/protobuf/json_format.py
index 7e40fdd..80f0103 100644
--- a/python/google/protobuf/json_format.py
+++ b/python/google/protobuf/json_format.py
@@ -570,7 +570,7 @@
setattr(message, field.name, _ConvertScalarFieldValue(value, field))
except ParseError as e:
if field and field.containing_oneof is None:
- raise ParseError('Failed to parse {0} field: {1}'.format(name, e))
+ raise ParseError('Failed to parse {0} field: {1}.'.format(name, e))
else:
raise ParseError(str(e))
except ValueError as e:
@@ -607,7 +607,10 @@
"""Convert a JSON representation into message with FromJsonString."""
# Duration, Timestamp, FieldMask have a FromJsonString method to do the
# conversion. Users can also call the method directly.
- message.FromJsonString(value)
+ try:
+ message.FromJsonString(value)
+ except ValueError as e:
+ raise ParseError(e)
def _ConvertValueMessage(self, value, message):
"""Convert a JSON representation into Value message."""
diff --git a/python/google/protobuf/proto_api.h b/python/google/protobuf/proto_api.h
index 47edf0e..75ee979 100644
--- a/python/google/protobuf/proto_api.h
+++ b/python/google/protobuf/proto_api.h
@@ -47,6 +47,7 @@
#include <Python.h>
+#include <google/protobuf/descriptor_database.h>
#include <google/protobuf/message.h>
namespace google {
@@ -76,6 +77,11 @@
// pointing to the message, like submessages or repeated containers.
// With the current implementation, only empty messages are in this case.
virtual Message* GetMutableMessagePointer(PyObject* msg) const = 0;
+
+ // Expose the underlying DescriptorPool and MessageFactory to enable C++ code
+ // to create Python-compatible message.
+ virtual const DescriptorPool* GetDefaultDescriptorPool() const = 0;
+ virtual MessageFactory* GetDefaultMessageFactory() const = 0;
};
inline const char* PyProtoAPICapsuleName() {
diff --git a/python/google/protobuf/pyext/extension_dict.cc b/python/google/protobuf/pyext/extension_dict.cc
index b73368e..7debe6f 100644
--- a/python/google/protobuf/pyext/extension_dict.cc
+++ b/python/google/protobuf/pyext/extension_dict.cc
@@ -65,6 +65,31 @@
namespace extension_dict {
+static Py_ssize_t len(ExtensionDict* self) {
+ Py_ssize_t size = 0;
+ std::vector<const FieldDescriptor*> fields;
+ self->parent->message->GetReflection()->ListFields(*self->parent->message,
+ &fields);
+
+ for (size_t i = 0; i < fields.size(); ++i) {
+ if (fields[i]->is_extension()) {
+ // With C++ descriptors, the field can always be retrieved, but for
+ // unknown extensions which have not been imported in Python code, there
+ // is no message class and we cannot retrieve the value.
+ // ListFields() has the same behavior.
+ if (fields[i]->message_type() != nullptr &&
+ message_factory::GetMessageClass(
+ cmessage::GetFactoryForMessage(self->parent),
+ fields[i]->message_type()) == nullptr) {
+ PyErr_Clear();
+ continue;
+ }
+ ++size;
+ }
+ }
+ return size;
+}
+
PyObject* subscript(ExtensionDict* self, PyObject* key) {
const FieldDescriptor* descriptor = cmessage::GetExtensionDescriptor(key);
if (descriptor == NULL) {
@@ -246,7 +271,7 @@
}
static PyMappingMethods MpMethods = {
- (lenfunc)NULL, /* mp_length */
+ (lenfunc)len, /* mp_length */
(binaryfunc)subscript, /* mp_subscript */
(objobjargproc)ass_subscript,/* mp_ass_subscript */
};
diff --git a/python/google/protobuf/pyext/message_module.cc b/python/google/protobuf/pyext/message_module.cc
index 8d465eb..4bb35b3 100644
--- a/python/google/protobuf/pyext/message_module.cc
+++ b/python/google/protobuf/pyext/message_module.cc
@@ -30,7 +30,9 @@
#include <Python.h>
+#include <google/protobuf/pyext/descriptor_pool.h>
#include <google/protobuf/pyext/message.h>
+#include <google/protobuf/pyext/message_factory.h>
#include <google/protobuf/proto_api.h>
#include <google/protobuf/message_lite.h>
@@ -45,37 +47,42 @@
google::protobuf::Message* GetMutableMessagePointer(PyObject* msg) const override {
return google::protobuf::python::PyMessage_GetMutableMessagePointer(msg);
}
+ const google::protobuf::DescriptorPool* GetDefaultDescriptorPool() const override {
+ return google::protobuf::python::GetDefaultDescriptorPool()->pool;
+ }
+
+ google::protobuf::MessageFactory* GetDefaultMessageFactory() const override {
+ return google::protobuf::python::GetDefaultDescriptorPool()
+ ->py_message_factory->message_factory;
+ }
};
} // namespace
static const char module_docstring[] =
-"python-proto2 is a module that can be used to enhance proto2 Python API\n"
-"performance.\n"
-"\n"
-"It provides access to the protocol buffers C++ reflection API that\n"
-"implements the basic protocol buffer functions.";
+ "python-proto2 is a module that can be used to enhance proto2 Python API\n"
+ "performance.\n"
+ "\n"
+ "It provides access to the protocol buffers C++ reflection API that\n"
+ "implements the basic protocol buffer functions.";
static PyMethodDef ModuleMethods[] = {
- {"SetAllowOversizeProtos",
- (PyCFunction)google::protobuf::python::cmessage::SetAllowOversizeProtos,
- METH_O, "Enable/disable oversize proto parsing."},
- // DO NOT USE: For migration and testing only.
- { NULL, NULL}
-};
+ {"SetAllowOversizeProtos",
+ (PyCFunction)google::protobuf::python::cmessage::SetAllowOversizeProtos, METH_O,
+ "Enable/disable oversize proto parsing."},
+ // DO NOT USE: For migration and testing only.
+ {NULL, NULL}};
#if PY_MAJOR_VERSION >= 3
-static struct PyModuleDef _module = {
- PyModuleDef_HEAD_INIT,
- "_message",
- module_docstring,
- -1,
- ModuleMethods, /* m_methods */
- NULL,
- NULL,
- NULL,
- NULL
-};
+static struct PyModuleDef _module = {PyModuleDef_HEAD_INIT,
+ "_message",
+ module_docstring,
+ -1,
+ ModuleMethods, /* m_methods */
+ NULL,
+ NULL,
+ NULL,
+ NULL};
#define INITFUNC PyInit__message
#define INITFUNC_ERRORVAL NULL
#else // Python 2
diff --git a/python/google/protobuf/pyext/repeated_composite_container.cc b/python/google/protobuf/pyext/repeated_composite_container.cc
index ca70058..f0b6e5d 100644
--- a/python/google/protobuf/pyext/repeated_composite_container.cc
+++ b/python/google/protobuf/pyext/repeated_composite_container.cc
@@ -159,10 +159,6 @@
}
PyObject* py_cmsg = reinterpret_cast<PyObject*>(cmsg);
- if (PyList_Append(self->child_messages, py_cmsg) < 0) {
- Py_DECREF(py_cmsg);
- return NULL;
- }
return py_cmsg;
}
@@ -174,6 +170,18 @@
// Create a new Message detached from the rest.
PyObject* py_cmsg = PyEval_CallObjectWithKeywords(
self->child_message_class->AsPyObject(), args, kwargs);
+ return py_cmsg;
+}
+
+PyObject* Add(RepeatedCompositeContainer* self,
+ PyObject* args,
+ PyObject* kwargs) {
+ PyObject* py_cmsg;
+ if (self->message == nullptr)
+ py_cmsg = AddToReleased(self, args, kwargs);
+ else
+ py_cmsg = AddToAttached(self, args, kwargs);
+
if (py_cmsg == NULL)
return NULL;
@@ -184,20 +192,98 @@
return py_cmsg;
}
-PyObject* Add(RepeatedCompositeContainer* self,
- PyObject* args,
- PyObject* kwargs) {
- if (self->message == NULL)
- return AddToReleased(self, args, kwargs);
- else
- return AddToAttached(self, args, kwargs);
-}
-
static PyObject* AddMethod(PyObject* self, PyObject* args, PyObject* kwargs) {
return Add(reinterpret_cast<RepeatedCompositeContainer*>(self), args, kwargs);
}
// ---------------------------------------------------------------------
+// append()
+
+static PyObject* AddMessage(RepeatedCompositeContainer* self, PyObject* value) {
+ cmessage::AssureWritable(self->parent);
+ if (UpdateChildMessages(self) < 0) {
+ return nullptr;
+ }
+
+ PyObject* py_cmsg;
+ if (self->message == nullptr) {
+ py_cmsg = AddToReleased(self, nullptr, nullptr);
+ if (py_cmsg == nullptr) return nullptr;
+ CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg);
+ if (ScopedPyObjectPtr(cmessage::MergeFrom(cmsg, value)) == nullptr) {
+ Py_DECREF(cmsg);
+ return nullptr;
+ }
+ } else {
+ Message* message = self->message;
+ const Reflection* reflection = message->GetReflection();
+ py_cmsg = AddToAttached(self, nullptr, nullptr);
+ if (py_cmsg == nullptr) return nullptr;
+ CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg);
+ if (ScopedPyObjectPtr(cmessage::MergeFrom(cmsg, value)) == nullptr) {
+ reflection->RemoveLast(
+ message, self->parent_field_descriptor);
+ Py_DECREF(cmsg);
+ return nullptr;
+ }
+ }
+ return py_cmsg;
+}
+
+static PyObject* AppendMethod(PyObject* pself, PyObject* value) {
+ RepeatedCompositeContainer* self =
+ reinterpret_cast<RepeatedCompositeContainer*>(pself);
+ PyObject* py_cmsg = AddMessage(self, value);
+ if (py_cmsg == nullptr) {
+ return nullptr;
+ }
+
+ if (PyList_Append(self->child_messages, py_cmsg) < 0) {
+ Py_DECREF(py_cmsg);
+ return nullptr;
+ }
+
+ Py_RETURN_NONE;
+}
+
+// ---------------------------------------------------------------------
+// insert()
+static PyObject* Insert(PyObject* pself, PyObject* args) {
+ RepeatedCompositeContainer* self =
+ reinterpret_cast<RepeatedCompositeContainer*>(pself);
+
+ Py_ssize_t index;
+ PyObject* value;
+ if (!PyArg_ParseTuple(args, "nO", &index, &value)) {
+ return nullptr;
+ }
+
+ PyObject* py_cmsg = AddMessage(self, value);
+ if (py_cmsg == nullptr) {
+ return nullptr;
+ }
+
+ if (self->message != nullptr) {
+ // Swap the element to right position.
+ Message* message = self->message;
+ const Reflection* reflection = message->GetReflection();
+ const FieldDescriptor* field_descriptor = self->parent_field_descriptor;
+ Py_ssize_t length = reflection->FieldSize(*message, field_descriptor) - 1;
+ Py_ssize_t end_index = index;
+ if (end_index < 0) end_index += length;
+ if (end_index < 0) end_index = 0;
+ for (Py_ssize_t i = length; i > end_index; i --) {
+ reflection->SwapElements(message, field_descriptor, i, i - 1);
+ }
+ }
+
+ if (PyList_Insert(self->child_messages, index, py_cmsg) < 0) {
+ return nullptr;
+ }
+ Py_RETURN_NONE;
+}
+
+// ---------------------------------------------------------------------
// extend()
PyObject* Extend(RepeatedCompositeContainer* self, PyObject* value) {
@@ -638,6 +724,10 @@
"Makes a deep copy of the class." },
{ "add", (PyCFunction)AddMethod, METH_VARARGS | METH_KEYWORDS,
"Adds an object to the repeated container." },
+ { "append", AppendMethod, METH_O,
+ "Appends a message to the end of the repeated container."},
+ { "insert", Insert, METH_VARARGS,
+ "Inserts a message before the specified index." },
{ "extend", ExtendMethod, METH_O,
"Adds objects to the repeated container." },
{ "pop", Pop, METH_VARARGS,
diff --git a/src/Makefile.am b/src/Makefile.am
index ff87338..a850508 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -200,6 +200,7 @@
google/protobuf/stubs/strutil.cc \
google/protobuf/stubs/time.cc \
google/protobuf/stubs/time.h \
+ google/protobuf/any_lite.cc \
google/protobuf/arena.cc \
google/protobuf/extension_set.cc \
google/protobuf/generated_message_util.cc \
diff --git a/src/google/protobuf/any.cc b/src/google/protobuf/any.cc
index b94529e..9d6d5cd 100644
--- a/src/google/protobuf/any.cc
+++ b/src/google/protobuf/any.cc
@@ -30,79 +30,35 @@
#include <google/protobuf/any.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/descriptor.h>
#include <google/protobuf/generated_message_util.h>
-
+#include <google/protobuf/message.h>
namespace google {
namespace protobuf {
namespace internal {
-namespace {
-string GetTypeUrl(const Descriptor* message,
- const string& type_url_prefix) {
- if (!type_url_prefix.empty() &&
- type_url_prefix[type_url_prefix.size() - 1] == '/') {
- return type_url_prefix + message->full_name();
- } else {
- return type_url_prefix + "/" + message->full_name();
- }
-}
-} // namespace
-
-const char kAnyFullTypeName[] = "google.protobuf.Any";
-const char kTypeGoogleApisComPrefix[] = "type.googleapis.com/";
-const char kTypeGoogleProdComPrefix[] = "type.googleprod.com/";
-
-AnyMetadata::AnyMetadata(UrlType* type_url, ValueType* value)
- : type_url_(type_url), value_(value) {
-}
-
void AnyMetadata::PackFrom(const Message& message) {
PackFrom(message, kTypeGoogleApisComPrefix);
}
void AnyMetadata::PackFrom(const Message& message,
const string& type_url_prefix) {
- type_url_->SetNoArena(&::google::protobuf::internal::GetEmptyString(),
- GetTypeUrl(message.GetDescriptor(), type_url_prefix));
+ type_url_->SetNoArena(
+ &::google::protobuf::internal::GetEmptyString(),
+ GetTypeUrl(message.GetDescriptor()->full_name(), type_url_prefix));
message.SerializeToString(value_->MutableNoArena(
&::google::protobuf::internal::GetEmptyStringAlreadyInited()));
}
bool AnyMetadata::UnpackTo(Message* message) const {
- if (!InternalIs(message->GetDescriptor())) {
+ if (!InternalIs(message->GetDescriptor()->full_name())) {
return false;
}
return message->ParseFromString(value_->GetNoArena());
}
-bool AnyMetadata::InternalIs(const Descriptor* descriptor) const {
- const string type_url = type_url_->GetNoArena();
- string full_name;
- if (!ParseAnyTypeUrl(type_url, &full_name)) {
- return false;
- }
- return full_name == descriptor->full_name();
-}
-
-bool ParseAnyTypeUrl(const string& type_url, string* url_prefix,
- string* full_type_name) {
- size_t pos = type_url.find_last_of("/");
- if (pos == string::npos || pos + 1 == type_url.size()) {
- return false;
- }
- if (url_prefix) {
- *url_prefix = type_url.substr(0, pos + 1);
- }
- *full_type_name = type_url.substr(pos + 1);
- return true;
-}
-
-bool ParseAnyTypeUrl(const string& type_url, string* full_type_name) {
- return ParseAnyTypeUrl(type_url, NULL, full_type_name);
-}
-
-
bool GetAnyFieldDescriptors(const Message& message,
const FieldDescriptor** type_url_field,
const FieldDescriptor** value_field) {
diff --git a/src/google/protobuf/any.h b/src/google/protobuf/any.h
index db7d76a..f5428c8 100644
--- a/src/google/protobuf/any.h
+++ b/src/google/protobuf/any.h
@@ -34,16 +34,26 @@
#include <string>
#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/message.h>
#include <google/protobuf/arenastring.h>
+#include <google/protobuf/message_lite.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
+
+class FieldDescriptor;
+class Message;
+
namespace internal {
+extern const char kAnyFullTypeName[]; // "google.protobuf.Any".
+extern const char kTypeGoogleApisComPrefix[]; // "type.googleapis.com/".
+extern const char kTypeGoogleProdComPrefix[]; // "type.googleprod.com/".
+
+std::string GetTypeUrl(StringPiece message_name,
+ StringPiece type_url_prefix);
+
// Helper class used to implement google::protobuf::Any.
class PROTOBUF_EXPORT AnyMetadata {
typedef ArenaStringPtr UrlType;
@@ -54,31 +64,52 @@
// Packs a message using the default type URL prefix: "type.googleapis.com".
// The resulted type URL will be "type.googleapis.com/<message_full_name>".
+ template <typename T>
+ void PackFrom(const T& message) {
+ InternalPackFrom(message, kTypeGoogleApisComPrefix, T::FullMessageName());
+ }
+
void PackFrom(const Message& message);
+
// Packs a message using the given type URL prefix. The type URL will be
// constructed by concatenating the message type's full name to the prefix
// with an optional "/" separator if the prefix doesn't already end up "/".
// For example, both PackFrom(message, "type.googleapis.com") and
// PackFrom(message, "type.googleapis.com/") yield the same result type
// URL: "type.googleapis.com/<message_full_name>".
+ template <typename T>
+ void PackFrom(const T& message, StringPiece type_url_prefix) {
+ InternalPackFrom(message, type_url_prefix, T::FullMessageName());
+ }
+
void PackFrom(const Message& message, const std::string& type_url_prefix);
// Unpacks the payload into the given message. Returns false if the message's
// type doesn't match the type specified in the type URL (i.e., the full
// name after the last "/" of the type URL doesn't match the message's actual
// full name) or parsing the payload has failed.
+ template <typename T>
+ bool UnpackTo(T* message) const {
+ return InternalUnpackTo(T::FullMessageName(), message);
+ }
+
bool UnpackTo(Message* message) const;
// Checks whether the type specified in the type URL matches the given type.
// A type is consdiered matching if its full name matches the full name after
// the last "/" in the type URL.
- template<typename T>
+ template <typename T>
bool Is() const {
- return InternalIs(T::default_instance().GetDescriptor());
+ return InternalIs(T::FullMessageName());
}
private:
- bool InternalIs(const Descriptor* message) const;
+ void InternalPackFrom(const MessageLite& message,
+ StringPiece type_url_prefix,
+ StringPiece type_name);
+ bool InternalUnpackTo(StringPiece type_name,
+ MessageLite* message) const;
+ bool InternalIs(StringPiece type_name) const;
UrlType* type_url_;
ValueType* value_;
@@ -86,10 +117,6 @@
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AnyMetadata);
};
-extern const char kAnyFullTypeName[]; // "google.protobuf.Any".
-extern const char kTypeGoogleApisComPrefix[]; // "type.googleapis.com/".
-extern const char kTypeGoogleProdComPrefix[]; // "type.googleprod.com/".
-
// Get the proto type name from Any::type_url value. For example, passing
// "type.googleapis.com/rpc.QueryOrigin" will return "rpc.QueryOrigin" in
// *full_type_name. Returns false if the type_url does not have a "/"
diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc
index 0b68e1d..8bd80e1 100644
--- a/src/google/protobuf/any.pb.cc
+++ b/src/google/protobuf/any.pb.cc
@@ -42,9 +42,9 @@
::google::protobuf::internal::InitSCC(&scc_info_Any_google_2fprotobuf_2fany_2eproto.base);
}
-::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fany_2eproto[1];
-constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto = nullptr;
-constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fany_2eproto = nullptr;
+static ::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fany_2eproto[1];
+static constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto = nullptr;
+static constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fany_2eproto = nullptr;
const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2fany_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
~0u, // no _has_bits_
@@ -63,7 +63,7 @@
reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Any_default_instance_),
};
-::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fany_2eproto = {
+static ::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fany_2eproto = {
{}, AddDescriptors_google_2fprotobuf_2fany_2eproto, "google/protobuf/any.proto", schemas,
file_default_instances, TableStruct_google_2fprotobuf_2fany_2eproto::offsets,
file_level_metadata_google_2fprotobuf_2fany_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto, file_level_service_descriptors_google_2fprotobuf_2fany_2eproto,
@@ -77,7 +77,7 @@
"\003GPB\252\002\036Google.Protobuf.WellKnownTypesb\006p"
"roto3"
;
-::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fany_2eproto = {
+static ::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fany_2eproto = {
false, InitDefaults_google_2fprotobuf_2fany_2eproto,
descriptor_table_protodef_google_2fprotobuf_2fany_2eproto,
"google/protobuf/any.proto", &assign_descriptors_table_google_2fprotobuf_2fany_2eproto, 205,
@@ -111,11 +111,6 @@
bool Any::UnpackTo(::google::protobuf::Message* message) const {
return _any_metadata_.UnpackTo(message);
}
-bool Any::ParseAnyTypeUrl(const string& type_url,
- string* full_type_name) {
- return ::google::protobuf::internal::ParseAnyTypeUrl(type_url,
- full_type_name);
-}
bool Any::GetAnyFieldDescriptors(
const ::google::protobuf::Message& message,
const ::google::protobuf::FieldDescriptor** type_url_field,
@@ -123,6 +118,11 @@
return ::google::protobuf::internal::GetAnyFieldDescriptors(
message, type_url_field, value_field);
}
+bool Any::ParseAnyTypeUrl(const string& type_url,
+ string* full_type_name) {
+ return ::google::protobuf::internal::ParseAnyTypeUrl(type_url,
+ full_type_name);
+}
class Any::HasBitSetters {
public:
@@ -192,71 +192,40 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* Any::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<Any*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* Any::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// string type_url = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(mutable_type_url(), ptr, ctx, "google.protobuf.Any.type_url");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.Any.type_url");
- object = msg->mutable_type_url();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// bytes value = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParser(mutable_value(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- object = msg->mutable_value();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParser;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheck(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool Any::MergePartialFromCodedStream(
diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h
index 5858b12..bcc2edb 100644
--- a/src/google/protobuf/any.pb.h
+++ b/src/google/protobuf/any.pb.h
@@ -108,15 +108,15 @@
void PackFrom(const ::google::protobuf::Message& message,
const ::std::string& type_url_prefix);
bool UnpackTo(::google::protobuf::Message* message) const;
+ static bool GetAnyFieldDescriptors(
+ const ::google::protobuf::Message& message,
+ const ::google::protobuf::FieldDescriptor** type_url_field,
+ const ::google::protobuf::FieldDescriptor** value_field);
template<typename T> bool Is() const {
return _any_metadata_.Is<T>();
}
static bool ParseAnyTypeUrl(const string& type_url,
string* full_type_name);
- static bool GetAnyFieldDescriptors(
- const ::google::protobuf::Message& message,
- const ::google::protobuf::FieldDescriptor** type_url_field,
- const ::google::protobuf::FieldDescriptor** value_field);
void Swap(Any* other);
friend void swap(Any& a, Any& b) {
a.Swap(&b);
@@ -140,8 +140,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -153,10 +152,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Any* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.Any";
+ }
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return nullptr;
diff --git a/src/google/protobuf/any_lite.cc b/src/google/protobuf/any_lite.cc
new file mode 100644
index 0000000..9356514
--- /dev/null
+++ b/src/google/protobuf/any_lite.cc
@@ -0,0 +1,123 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/any.h>
+
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/stubs/strutil.h>
+
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+string GetTypeUrl(StringPiece message_name,
+ StringPiece type_url_prefix) {
+ if (!type_url_prefix.empty() &&
+ type_url_prefix[type_url_prefix.size() - 1] == '/') {
+ return StrCat(type_url_prefix, message_name);
+ } else {
+ return StrCat(type_url_prefix, "/", message_name);
+ }
+}
+
+const char kAnyFullTypeName[] = "google.protobuf.Any";
+const char kTypeGoogleApisComPrefix[] = "type.googleapis.com/";
+const char kTypeGoogleProdComPrefix[] = "type.googleprod.com/";
+
+AnyMetadata::AnyMetadata(UrlType* type_url, ValueType* value)
+ : type_url_(type_url), value_(value) {}
+
+void AnyMetadata::InternalPackFrom(const MessageLite& message,
+ StringPiece type_url_prefix,
+ StringPiece type_name) {
+ type_url_->SetNoArena(&::google::protobuf::internal::GetEmptyString(),
+ GetTypeUrl(type_name, type_url_prefix));
+ message.SerializeToString(value_->MutableNoArena(
+ &::google::protobuf::internal::GetEmptyStringAlreadyInited()));
+}
+
+bool AnyMetadata::InternalUnpackTo(StringPiece type_name,
+ MessageLite* message) const {
+ if (!InternalIs(type_name)) {
+ return false;
+ }
+ return message->ParseFromString(value_->GetNoArena());
+}
+
+namespace {
+
+// The type URL could be stored in either an ArenaStringPtr or a
+// StringPieceField, so we provide these helpers to get a string_view from
+// either type. We use a template function as a way to avoid depending on
+// StringPieceField.
+
+template <typename T>
+StringPiece Get(const T* ptr) {
+ return ptr->Get();
+}
+
+template <>
+// NOLINTNEXTLINE: clang-diagnostic-unused-function
+StringPiece Get(const ArenaStringPtr* ptr) {
+ return ptr->GetNoArena();
+}
+
+} // namespace
+
+bool AnyMetadata::InternalIs(StringPiece type_name) const {
+ StringPiece type_url = Get(type_url_);
+ return type_url.size() >= type_name.size() + 1 &&
+ type_url[type_url.size() - type_name.size() - 1] == '/' &&
+ HasSuffixString(type_url, type_name);
+}
+
+bool ParseAnyTypeUrl(const string& type_url, string* url_prefix,
+ string* full_type_name) {
+ size_t pos = type_url.find_last_of("/");
+ if (pos == string::npos || pos + 1 == type_url.size()) {
+ return false;
+ }
+ if (url_prefix) {
+ *url_prefix = type_url.substr(0, pos + 1);
+ }
+ *full_type_name = type_url.substr(pos + 1);
+ return true;
+}
+
+bool ParseAnyTypeUrl(const string& type_url, string* full_type_name) {
+ return ParseAnyTypeUrl(type_url, nullptr, full_type_name);
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/any_test.cc b/src/google/protobuf/any_test.cc
index 514ac51..378981c 100644
--- a/src/google/protobuf/any_test.cc
+++ b/src/google/protobuf/any_test.cc
@@ -29,9 +29,11 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/any_test.pb.h>
+#include <google/protobuf/unittest.pb.h>
#include <gtest/gtest.h>
+
namespace google {
namespace protobuf {
namespace {
@@ -46,10 +48,22 @@
ASSERT_TRUE(message.ParseFromString(data));
EXPECT_TRUE(message.has_any_value());
+ submessage.Clear();
ASSERT_TRUE(message.any_value().UnpackTo(&submessage));
EXPECT_EQ(12345, submessage.int32_value());
}
+TEST(AnyTest, TestUnpackWithTypeMismatch) {
+ protobuf_unittest::TestAny payload;
+ payload.set_int32_value(13);
+ google::protobuf::Any any;
+ any.PackFrom(payload);
+
+ // Attempt to unpack into the wrong type.
+ protobuf_unittest::TestAllTypes dest;
+ EXPECT_FALSE(any.UnpackTo(&dest));
+}
+
TEST(AnyTest, TestPackAndUnpackAny) {
// We can pack a Any message inside another Any message.
protobuf_unittest::TestAny submessage;
@@ -63,26 +77,26 @@
ASSERT_TRUE(message.ParseFromString(data));
EXPECT_TRUE(message.has_any_value());
+ any.Clear();
+ submessage.Clear();
ASSERT_TRUE(message.any_value().UnpackTo(&any));
ASSERT_TRUE(any.UnpackTo(&submessage));
EXPECT_EQ(12345, submessage.int32_value());
}
-TEST(AnyType, TestPackWithCustomTypeUrl) {
+TEST(AnyTest, TestPackWithCustomTypeUrl) {
protobuf_unittest::TestAny submessage;
submessage.set_int32_value(12345);
google::protobuf::Any any;
// Pack with a custom type URL prefix.
any.PackFrom(submessage, "type.myservice.com");
- EXPECT_EQ("type.myservice.com/" + submessage.GetDescriptor()->full_name(),
- any.type_url());
+ EXPECT_EQ("type.myservice.com/protobuf_unittest.TestAny", any.type_url());
// Pack with a custom type URL prefix ending with '/'.
any.PackFrom(submessage, "type.myservice.com/");
- EXPECT_EQ("type.myservice.com/" + submessage.GetDescriptor()->full_name(),
- any.type_url());
+ EXPECT_EQ("type.myservice.com/protobuf_unittest.TestAny", any.type_url());
// Pack with an empty type URL prefix.
any.PackFrom(submessage, "");
- EXPECT_EQ("/" + submessage.GetDescriptor()->full_name(), any.type_url());
+ EXPECT_EQ("/protobuf_unittest.TestAny", any.type_url());
// Test unpacking the type.
submessage.Clear();
@@ -104,6 +118,15 @@
ASSERT_TRUE(message.ParseFromString(message.SerializeAsString()));
EXPECT_FALSE(message.any_value().Is<protobuf_unittest::TestAny>());
EXPECT_TRUE(message.any_value().Is<google::protobuf::Any>());
+
+ any.set_type_url("/protobuf_unittest.TestAny");
+ EXPECT_TRUE(any.Is<protobuf_unittest::TestAny>());
+ // The type URL must contain at least one "/".
+ any.set_type_url("protobuf_unittest.TestAny");
+ EXPECT_FALSE(any.Is<protobuf_unittest::TestAny>());
+ // The type name after the slash must be fully qualified.
+ any.set_type_url("/TestAny");
+ EXPECT_FALSE(any.Is<protobuf_unittest::TestAny>());
}
TEST(AnyTest, MoveConstructor) {
@@ -117,6 +140,7 @@
google::protobuf::Any dst(std::move(src));
EXPECT_EQ(type_url, dst.type_url().data());
+ payload.Clear();
ASSERT_TRUE(dst.UnpackTo(&payload));
EXPECT_EQ(12345, payload.int32_value());
}
@@ -133,6 +157,7 @@
google::protobuf::Any dst;
dst = std::move(src);
EXPECT_EQ(type_url, dst.type_url().data());
+ payload.Clear();
ASSERT_TRUE(dst.UnpackTo(&payload));
EXPECT_EQ(12345, payload.int32_value());
}
diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc
index 2a6ca2b..8fe7301 100644
--- a/src/google/protobuf/api.pb.cc
+++ b/src/google/protobuf/api.pb.cc
@@ -89,9 +89,9 @@
::google::protobuf::internal::InitSCC(&scc_info_Mixin_google_2fprotobuf_2fapi_2eproto.base);
}
-::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fapi_2eproto[3];
-constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr;
-constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr;
+static ::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fapi_2eproto[3];
+static constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr;
+static constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr;
const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2fapi_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
~0u, // no _has_bits_
@@ -138,7 +138,7 @@
reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Mixin_default_instance_),
};
-::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fapi_2eproto = {
+static ::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fapi_2eproto = {
{}, AddDescriptors_google_2fprotobuf_2fapi_2eproto, "google/protobuf/api.proto", schemas,
file_default_instances, TableStruct_google_2fprotobuf_2fapi_2eproto::offsets,
file_level_metadata_google_2fprotobuf_2fapi_2eproto, 3, file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto, file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto,
@@ -165,7 +165,7 @@
"nproto/protobuf/api;api\242\002\003GPB\252\002\036Google.P"
"rotobuf.WellKnownTypesb\006proto3"
;
-::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto = {
+static ::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto = {
false, InitDefaults_google_2fprotobuf_2fapi_2eproto,
descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto,
"google/protobuf/api.proto", &assign_descriptors_table_google_2fprotobuf_2fapi_2eproto, 750,
@@ -298,141 +298,85 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* Api::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<Api*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* Api::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// string name = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(mutable_name(), ptr, ctx, "google.protobuf.Api.name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.Api.name");
- object = msg->mutable_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// repeated .google.protobuf.Method methods = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_methods(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::Method::_InternalParse;
- object = msg->add_methods();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
break;
}
// repeated .google.protobuf.Option options = 3;
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_options(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::Option::_InternalParse;
- object = msg->add_options();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
break;
}
// string version = 4;
case 4: {
if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(mutable_version(), ptr, ctx, "google.protobuf.Api.version");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.Api.version");
- object = msg->mutable_version();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// .google.protobuf.SourceContext source_context = 5;
case 5: {
if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(mutable_source_context(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::SourceContext::_InternalParse;
- object = msg->mutable_source_context();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
break;
}
// repeated .google.protobuf.Mixin mixins = 6;
case 6: {
if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_mixins(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::Mixin::_InternalParse;
- object = msg->add_mixins();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 50 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 50 && (ptr += 1));
break;
}
// .google.protobuf.Syntax syntax = 7;
case 7: {
if (static_cast<::google::protobuf::uint8>(tag) != 56) goto handle_unusual;
::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
- msg->set_syntax(static_cast<::google::protobuf::Syntax>(val));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ set_syntax(static_cast<::google::protobuf::Syntax>(val));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool Api::MergePartialFromCodedStream(
@@ -957,77 +901,44 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* Method::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<Method*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* Method::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// string name = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(mutable_name(), ptr, ctx, "google.protobuf.Method.name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.Method.name");
- object = msg->mutable_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// string request_type_url = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(mutable_request_type_url(), ptr, ctx, "google.protobuf.Method.request_type_url");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.Method.request_type_url");
- object = msg->mutable_request_type_url();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// bool request_streaming = 3;
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
- msg->set_request_streaming(::google::protobuf::internal::ReadVarint(&ptr));
+ set_request_streaming(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// string response_type_url = 4;
case 4: {
if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(mutable_response_type_url(), ptr, ctx, "google.protobuf.Method.response_type_url");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.Method.response_type_url");
- object = msg->mutable_response_type_url();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// bool response_streaming = 5;
case 5: {
if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
- msg->set_response_streaming(::google::protobuf::internal::ReadVarint(&ptr));
+ set_response_streaming(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
@@ -1035,48 +946,34 @@
case 6: {
if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_options(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::Option::_InternalParse;
- object = msg->add_options();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 50 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 50 && (ptr += 1));
break;
}
// .google.protobuf.Syntax syntax = 7;
case 7: {
if (static_cast<::google::protobuf::uint8>(tag) != 56) goto handle_unusual;
::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
- msg->set_syntax(static_cast<::google::protobuf::Syntax>(val));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ set_syntax(static_cast<::google::protobuf::Syntax>(val));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool Method::MergePartialFromCodedStream(
@@ -1571,72 +1468,40 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* Mixin::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<Mixin*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* Mixin::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// string name = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(mutable_name(), ptr, ctx, "google.protobuf.Mixin.name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.Mixin.name");
- object = msg->mutable_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// string root = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(mutable_root(), ptr, ctx, "google.protobuf.Mixin.root");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.Mixin.root");
- object = msg->mutable_root();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool Mixin::MergePartialFromCodedStream(
diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h
index 11e8196..6e63871 100644
--- a/src/google/protobuf/api.pb.h
+++ b/src/google/protobuf/api.pb.h
@@ -31,6 +31,13 @@
#include <google/protobuf/repeated_field.h> // IWYU pragma: export
#include <google/protobuf/extension_set.h> // IWYU pragma: export
#include <google/protobuf/unknown_field_set.h>
+namespace google {
+namespace protobuf {
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+} // namespace protobuf
+} // namespace google
#include <google/protobuf/source_context.pb.h>
#include <google/protobuf/type.pb.h>
// @@protoc_insertion_point(includes)
@@ -134,8 +141,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -147,10 +153,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Api* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.Api";
+ }
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return nullptr;
@@ -325,8 +335,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -338,10 +347,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Method* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.Method";
+ }
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return nullptr;
@@ -509,8 +522,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -522,10 +534,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Mixin* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.Mixin";
+ }
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return nullptr;
diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h
index a38a802..bd56239 100644
--- a/src/google/protobuf/arena.h
+++ b/src/google/protobuf/arena.h
@@ -34,6 +34,7 @@
#define GOOGLE_PROTOBUF_ARENA_H__
#include <limits>
+#include <type_traits>
#ifdef max
#undef max // Visual Studio defines this macro
#endif
@@ -156,13 +157,14 @@
private:
// Hooks for adding external functionality such as user-specific metrics
// collection, specific debugging abilities, etc.
- // Init hook may return a pointer to a cookie to be stored in the arena.
- // reset and destruction hooks will then be called with the same cookie
- // pointer. This allows us to save an external object per arena instance and
- // use it on the other hooks (Note: It is just as legal for init to return
- // NULL and not use the cookie feature).
- // on_arena_reset and on_arena_destruction also receive the space used in
- // the arena just before the reset.
+ // Init hook (if set) will always be called at Arena init time. Init hook may
+ // return a pointer to a cookie to be stored in the arena. Reset and
+ // destruction hooks will then be called with the same cookie pointer. This
+ // allows us to save an external object per arena instance and use it on the
+ // other hooks (Note: If init hook returns NULL, the other hooks will NOT be
+ // called on this arena instance).
+ // on_arena_reset and on_arena_destruction also receive the space used in the
+ // arena just before the reset.
void* (*on_arena_init)(Arena* arena);
void (*on_arena_reset)(Arena* arena, void* cookie, uint64 space_used);
void (*on_arena_destruction)(Arena* arena, void* cookie, uint64 space_used);
@@ -408,12 +410,12 @@
}
// Retrieves the arena associated with |value| if |value| is an arena-capable
- // message, or NULL otherwise. This differs from value->GetArena() in that the
- // latter is a virtual call, while this method is a templated call that
- // resolves at compile-time.
+ // message, or NULL otherwise. If possible, the call resolves at compile time.
+ // Note that we can often devirtualize calls to `value->GetArena()` so usually
+ // calling this method is unnecessary.
template <typename T>
PROTOBUF_ALWAYS_INLINE static Arena* GetArena(const T* value) {
- return GetArenaInternal(value, is_arena_constructable<T>());
+ return GetArenaInternal(value);
}
template <typename T>
@@ -440,6 +442,15 @@
sizeof(char)>
is_arena_constructable;
+ template <typename U>
+ static char HasGetArena(decltype(&U::GetArena));
+ template <typename U>
+ static double HasGetArena(...);
+
+ typedef std::integral_constant<bool, sizeof(HasGetArena<T>(nullptr)) ==
+ sizeof(char)>
+ has_get_arena;
+
template <typename... Args>
static T* Construct(void* ptr, Args&&... args) {
return new (ptr) T(std::forward<Args>(args)...);
@@ -655,16 +666,24 @@
// Implementation for GetArena(). Only message objects with
// InternalArenaConstructable_ tags can be associated with an arena, and such
// objects must implement a GetArenaNoVirtual() method.
- template <typename T>
- PROTOBUF_ALWAYS_INLINE static Arena* GetArenaInternal(const T* value,
- std::true_type) {
+ template <typename T, typename std::enable_if<
+ is_arena_constructable<T>::value, int>::type = 0>
+ PROTOBUF_ALWAYS_INLINE static Arena* GetArenaInternal(const T* value) {
return InternalHelper<T>::GetArena(value);
}
-
- template <typename T>
- PROTOBUF_ALWAYS_INLINE static Arena* GetArenaInternal(const T* /* value */,
- std::false_type) {
- return NULL;
+ template <typename T,
+ typename std::enable_if<!is_arena_constructable<T>::value &&
+ InternalHelper<T>::has_get_arena::value,
+ int>::type = 0>
+ PROTOBUF_ALWAYS_INLINE static Arena* GetArenaInternal(const T* value) {
+ return value->GetArena();
+ }
+ template <typename T, typename std::enable_if<
+ !is_arena_constructable<T>::value &&
+ !InternalHelper<T>::has_get_arena::value,
+ int>::type = 0>
+ PROTOBUF_ALWAYS_INLINE static Arena* GetArenaInternal(const T* value) {
+ return nullptr;
}
// For friends of arena.
diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc
index a942cff..9fdcda5 100644
--- a/src/google/protobuf/arena_unittest.cc
+++ b/src/google/protobuf/arena_unittest.cc
@@ -1324,6 +1324,12 @@
const ArenaMessage* const_pointer_to_message = message;
EXPECT_EQ(&arena, Arena::GetArena(message));
EXPECT_EQ(&arena, Arena::GetArena(const_pointer_to_message));
+
+ // Test that the Message* / MessageLite* specialization SFINAE works.
+ const Message* const_pointer_to_message_type = message;
+ EXPECT_EQ(&arena, Arena::GetArena(const_pointer_to_message_type));
+ const MessageLite* const_pointer_to_message_lite_type = message;
+ EXPECT_EQ(&arena, Arena::GetArena(const_pointer_to_message_lite_type));
}
TEST(ArenaTest, GetArenaShouldReturnNullForNonArenaAllocatedMessages) {
diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc
index 4dc4725..54bec72 100644
--- a/src/google/protobuf/compiler/command_line_interface_unittest.cc
+++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -2463,9 +2463,8 @@
"net/proto2/internal/no_such_file.proto: No such file or directory\n");
}
-INSTANTIATE_TEST_CASE_P(FileDescriptorSetSource,
- EncodeDecodeTest,
- testing::Values(PROTO_PATH, DESCRIPTOR_SET_IN));
+INSTANTIATE_TEST_SUITE_P(FileDescriptorSetSource, EncodeDecodeTest,
+ testing::Values(PROTO_PATH, DESCRIPTOR_SET_IN));
} // anonymous namespace
#endif // !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.cc b/src/google/protobuf/compiler/cpp/cpp_enum.cc
index 39fe9e6..66e56d0 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum.cc
@@ -72,7 +72,6 @@
variables_["short_name"] = descriptor_->name();
variables_["enumbase"] = options_.proto_h ? " : int" : "";
variables_["nested_name"] = descriptor_->name();
- variables_["constexpr"] = options_.proto_h ? "constexpr" : "";
variables_["prefix"] =
(descriptor_->containing_type() == NULL) ? "" : classname_ + "_";
}
@@ -127,15 +126,15 @@
format(
"$dllexport_decl $bool $classname$_IsValid(int value);\n"
- "const $classname$ ${1$$prefix$$short_name$_MIN$}$ = "
+ "constexpr $classname$ ${1$$prefix$$short_name$_MIN$}$ = "
"$prefix$$2$;\n"
- "const $classname$ ${1$$prefix$$short_name$_MAX$}$ = "
+ "constexpr $classname$ ${1$$prefix$$short_name$_MAX$}$ = "
"$prefix$$3$;\n",
descriptor_, EnumValueName(min_value), EnumValueName(max_value));
if (generate_array_size_) {
format(
- "const int ${1$$prefix$$short_name$_ARRAYSIZE$}$ = "
+ "constexpr int ${1$$prefix$$short_name$_ARRAYSIZE$}$ = "
"$prefix$$short_name$_MAX + 1;\n\n",
descriptor_);
}
@@ -199,7 +198,7 @@
string deprecated_attr = DeprecatedAttribute(
options_, descriptor_->value(j)->options().deprecated());
format(
- "$1$static $constexpr $const $nested_name$ ${2$$3$$}$ =\n"
+ "$1$static constexpr $nested_name$ ${2$$3$$}$ =\n"
" $classname$_$3$;\n",
deprecated_attr, descriptor_->value(j),
EnumValueName(descriptor_->value(j)));
@@ -209,14 +208,14 @@
"static inline bool $nested_name$_IsValid(int value) {\n"
" return $classname$_IsValid(value);\n"
"}\n"
- "static const $nested_name$ ${1$$nested_name$_MIN$}$ =\n"
+ "static constexpr $nested_name$ ${1$$nested_name$_MIN$}$ =\n"
" $classname$_$nested_name$_MIN;\n"
- "static const $nested_name$ ${1$$nested_name$_MAX$}$ =\n"
+ "static constexpr $nested_name$ ${1$$nested_name$_MAX$}$ =\n"
" $classname$_$nested_name$_MAX;\n",
descriptor_);
if (generate_array_size_) {
format(
- "static const int ${1$$nested_name$_ARRAYSIZE$}$ =\n"
+ "static constexpr int ${1$$nested_name$_ARRAYSIZE$}$ =\n"
" $classname$_$nested_name$_ARRAYSIZE;\n",
descriptor_);
}
@@ -297,25 +296,26 @@
if (descriptor_->containing_type() != NULL) {
string parent = ClassName(descriptor_->containing_type(), false);
- // We need to "define" the static constants which were declared in the
- // header, to give the linker a place to put them. Or at least the C++
- // standard says we have to. MSVC actually insists that we do _not_ define
- // them again in the .cc file, prior to VC++ 2015.
- format("#if !defined(_MSC_VER) || _MSC_VER >= 1900\n");
+ // Before C++17, we must define the static constants which were
+ // declared in the header, to give the linker a place to put them.
+ // But pre-2015 MSVC++ insists that we not.
+ format("#if (__cplusplus < 201703) && "
+ "(!defined(_MSC_VER) || _MSC_VER >= 1900)\n");
for (int i = 0; i < descriptor_->value_count(); i++) {
- format("$constexpr $const $classname$ $1$::$2$;\n", parent,
+ format("constexpr $classname$ $1$::$2$;\n", parent,
EnumValueName(descriptor_->value(i)));
}
format(
- "const $classname$ $1$::$nested_name$_MIN;\n"
- "const $classname$ $1$::$nested_name$_MAX;\n",
+ "constexpr $classname$ $1$::$nested_name$_MIN;\n"
+ "constexpr $classname$ $1$::$nested_name$_MAX;\n",
parent);
if (generate_array_size_) {
- format("const int $1$::$nested_name$_ARRAYSIZE;\n", parent);
+ format("constexpr int $1$::$nested_name$_ARRAYSIZE;\n", parent);
}
- format("#endif // !defined(_MSC_VER) || _MSC_VER >= 1900\n");
+ format("#endif // (__cplusplus < 201703) && "
+ "(!defined(_MSC_VER) || _MSC_VER >= 1900)\n");
}
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index e9abeff..24c88d3 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -706,29 +706,34 @@
// in the file.
if (!message_generators_.empty()) {
- format("::$proto_ns$::Metadata $file_level_metadata$[$1$];\n",
+ format("static ::$proto_ns$::Metadata $file_level_metadata$[$1$];\n",
message_generators_.size());
} else {
format(
+ "static "
"constexpr ::$proto_ns$::Metadata* $file_level_metadata$ = nullptr;\n");
}
if (!enum_generators_.empty()) {
format(
+ "static "
"const ::$proto_ns$::EnumDescriptor* "
"$file_level_enum_descriptors$[$1$];\n",
enum_generators_.size());
} else {
format(
+ "static "
"constexpr ::$proto_ns$::EnumDescriptor const** "
"$file_level_enum_descriptors$ = nullptr;\n");
}
if (HasGenericServices(file_, options_) && file_->service_count() > 0) {
format(
+ "static "
"const ::$proto_ns$::ServiceDescriptor* "
"$file_level_service_descriptors$[$1$];\n",
file_->service_count());
} else {
format(
+ "static "
"constexpr ::$proto_ns$::ServiceDescriptor const** "
"$file_level_service_descriptors$ = nullptr;\n");
}
@@ -795,6 +800,7 @@
// AssignDescriptors(). All later times, waits for the first call to
// complete and then returns.
format(
+ "static "
"::$proto_ns$::internal::AssignDescriptorsTable $assign_desc_table$ = "
"{\n"
" {}, $add_descriptors$, \"$filename$\", schemas,\n"
@@ -846,6 +852,7 @@
// Now generate the AddDescriptors() function.
format(
+ "static "
"::$proto_ns$::internal::DescriptorTable $1$ = {\n"
" false, $init_defaults$, \n"
" $2$,\n",
@@ -1295,6 +1302,26 @@
if (IsAnyMessage(file_, options_)) {
IncludeFile("net/proto2/internal/any.h", printer);
+ } else {
+ // For Any support with lite protos, we need to friend AnyMetadata, so we
+ // forward-declare it here.
+ if (options_.opensource_runtime) {
+ format(
+ "namespace google {\n"
+ "namespace protobuf {\n"
+ "namespace internal {\n"
+ "class AnyMetadata;\n"
+ "} // namespace internal\n"
+ "} // namespace protobuf\n"
+ "} // namespace google\n");
+ } else {
+ format(
+ "namespace google {\nnamespace protobuf {\n"
+ "namespace internal {\n"
+ "class AnyMetadata;\n"
+ "} // namespace internal\n"
+ "} // namespace protobuf\n} // namespace google\n");
+ }
}
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
index e6cbdf4..a3bd81f 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -32,6 +32,7 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
+#include <functional>
#include <limits>
#include <map>
#include <queue>
@@ -75,7 +76,7 @@
return StringReplace(name, ".", "::", true);
}
-const char* const kKeywordList[] = { //
+static const char* const kKeywordList[] = { //
"NULL",
"alignas",
"alignof",
@@ -160,15 +161,15 @@
"xor",
"xor_eq"};
-std::unordered_set<string> MakeKeywordsMap() {
- std::unordered_set<string> result;
- for (int i = 0; i < GOOGLE_ARRAYSIZE(kKeywordList); i++) {
- result.insert(kKeywordList[i]);
+static std::unordered_set<string>* MakeKeywordsMap() {
+ auto* result = new std::unordered_set<string>();
+ for (const auto keyword : kKeywordList) {
+ result->emplace(keyword);
}
return result;
}
-std::unordered_set<string> kKeywords = MakeKeywordsMap();
+static std::unordered_set<string>& kKeywords = *MakeKeywordsMap();
// Returns whether the provided descriptor has an extension. This includes its
// nested types.
@@ -255,6 +256,7 @@
"ECK";
}
+ SetIntVar(options, "int8", variables);
SetIntVar(options, "uint8", variables);
SetIntVar(options, "uint32", variables);
SetIntVar(options, "uint64", variables);
@@ -910,11 +912,7 @@
}
bool IsAnyMessage(const FileDescriptor* descriptor, const Options& options) {
- // For now we do not support Any in lite mode, so if we're building for lite
- // then we just treat Any as if it's an ordinary message with no special
- // behavior.
- return descriptor->name() == kAnyProtoFile &&
- GetOptimizeFor(descriptor, options) != FileOptions::LITE_RUNTIME;
+ return descriptor->name() == kAnyProtoFile;
}
bool IsAnyMessage(const Descriptor* descriptor, const Options& options) {
@@ -1302,14 +1300,20 @@
void GenerateParserLoop(const Descriptor* descriptor) {
format_.Set("classname", ClassName(descriptor));
- format_.Set("proto_ns", ProtobufNamespace(options_));
+ format_.Set("p_ns", "::" + ProtobufNamespace(options_));
+ format_.Set("pi_ns", StrCat("::", ProtobufNamespace(options_), "::internal"));
format_.Set("GOOGLE_PROTOBUF", MacroPrefix(options_));
+ format_.Set("kSlopBytes",
+ static_cast<int>(internal::ParseContext::kSlopBytes));
std::map<string, string> vars;
SetCommonVars(options_, &vars);
format_.AddMap(vars);
std::vector<const FieldDescriptor*> ordered_fields;
for (auto field : FieldRange(descriptor)) {
+ if (IsProto1(descriptor->file(), options_)) {
+ if (field->number() >= (1 << 14)) continue;
+ }
ordered_fields.push_back(field);
}
std::sort(ordered_fields.begin(), ordered_fields.end(),
@@ -1318,19 +1322,11 @@
});
format_(
- "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"
- " $int32$ size; (void)size;\n"
- " int depth; (void)depth;\n"
- " $uint32$ tag;\n"
- " ::$proto_ns$::internal::ParseFunc parser_till_end; "
- "(void)parser_till_end;\n"
- " auto ptr = begin;\n"
- " while (ptr < end) {\n"
- " ptr = ::$proto_ns$::io::Parse32(ptr, &tag);\n"
+ "const char* $classname$::_InternalParse(const char* ptr, "
+ "$pi_ns$::ParseContext* ctx) {\n"
+ " while (!ctx->Done(&ptr)) {\n"
+ " $uint32$ tag;\n"
+ " ptr = $pi_ns$::ReadTag(ptr, &tag);\n"
" $GOOGLE_PROTOBUF$_PARSER_ASSERT(ptr);\n"
" switch (tag >> 3) {\n");
@@ -1338,11 +1334,7 @@
format_.Indent();
format_.Indent();
- bool use_handle_unusual = false;
for (const auto* field : ordered_fields) {
- if (IsProto1(descriptor->file(), options_)) {
- if (field->number() >= (1 << 14)) continue;
- }
// Print the field's (or oneof's) proto-syntax definition as a comment.
// We don't want to print group bodies so we cut off after the first
// line.
@@ -1359,22 +1351,21 @@
"case $2$: {\n",
def, field->number());
format_.Indent();
- use_handle_unusual = true;
GenerateCaseBody(field);
format_.Outdent();
format_("}\n"); // case
} // for fields
+
+ // Default case
format_("default: {\n");
- if (use_handle_unusual) format_("handle_unusual:\n");
+ if (!ordered_fields.empty()) format_("handle_unusual:\n");
format_(
" if ((tag & 7) == 4 || tag == 0) {\n"
- " ctx->EndGroup(tag);\n"
+ " ctx->SetLastTag(tag);\n"
" return ptr;\n"
" }\n");
if (IsMapEntryMessage(descriptor)) {
- format_(
- " break;\n"
- "}\n");
+ format_(" break;\n");
} else {
if (descriptor->extension_range_count() > 0) {
format_("if (");
@@ -1396,113 +1387,59 @@
}
format_(") {\n");
format_(
- " auto res = msg->_extensions_.ParseField(tag, {_InternalParse, "
- "msg}, ptr, end,\n"
- " internal_default_instance(), &msg->_internal_metadata_, "
+ " ptr = _extensions_.ParseField(tag, ptr, \n"
+ " internal_default_instance(), &_internal_metadata_, "
"ctx);\n"
- " ptr = res.first;\n"
" $GOOGLE_PROTOBUF$_PARSER_ASSERT(ptr != nullptr);\n"
- " if (res.second) return ptr;\n"
- " continue;\n"
+ " break;\n"
"}\n");
}
format_(
- " auto res = UnknownFieldParse(tag, {_InternalParse, msg},\n"
- " ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), "
- "ctx);\n"
- " ptr = res.first;\n"
+ " ptr = UnknownFieldParse(tag,\n"
+ " _internal_metadata_.mutable_unknown_fields(), ptr, ctx);\n"
" $GOOGLE_PROTOBUF$_PARSER_ASSERT(ptr != nullptr);\n"
- " if (res.second) return ptr;\n"
- "}\n"); // default case
+ " break;\n");
}
+ format_("}\n"); // default case
format_.Outdent();
format_.Outdent();
format_.Outdent();
format_(
" } // switch\n"
" } // while\n"
- " return ptr;\n");
- if (use_string_) {
- format_(
- "string_till_end:\n"
- " static_cast<$string$*>(object)->clear();\n"
- // TODO(gerbens) evaluate security
- " static_cast<$string$*>(object)->reserve(size);\n"
- " goto len_delim_till_end;\n");
- }
- if (use_arena_string_) {
- format_(
- "arena_string_till_end:\n"
- " object = "
- "static_cast<::$proto_ns$::internal::ArenaStringPtr*>(object)->"
- "Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), "
- "msg->GetArenaNoVirtual());\n"
- " static_cast<$string$*>(object)->clear();\n"
- // TODO(gerbens) evaluate security
- " static_cast<$string$*>(object)->reserve(size);\n"
- " goto len_delim_till_end;\n");
- }
- if (use_length_delimited_) {
- format_(
- "len_delim_till_end:\n"
- " return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},\n"
- " {parser_till_end, object}, size);\n");
- }
- if (use_group_) {
- // Group crossed end and must be continued. Either this a parse failure
- // or we need to resume on the next chunk and thus save the state.
- format_(
- "group_continues:\n"
- " $DCHK$(ptr >= end);\n"
- " $GOOGLE_PROTOBUF$_PARSER_ASSERT(ctx->StoreGroup(\n "
- " {_InternalParse, msg}, {parser_till_end, object}, depth, tag));\n"
- " return ptr;\n");
- }
- format_("}\n");
+ " return ptr;\n"
+ "}\n");
}
private:
MessageSCCAnalyzer* scc_analyzer_;
const Options& options_;
Formatter format_;
- bool use_length_delimited_ = false;
- bool use_group_ = false;
- bool use_string_ = false;
- bool use_arena_string_ = false;
using WireFormat = internal::WireFormat;
using WireFormatLite = internal::WireFormatLite;
- void GenerateArenaString(const FieldDescriptor* field, const string& utf8) {
- use_arena_string_ = true;
+ void GenerateArenaString(const FieldDescriptor* field, const string& utf8,
+ const string& field_name) {
if (HasFieldPresence(field->file())) {
- format_("HasBitSetters::set_has_$1$(msg);\n", FieldName(field));
+ format_("HasBitSetters::set_has_$1$(this);\n", FieldName(field));
}
format_(
- "if (size > end - ptr + "
- "::$proto_ns$::internal::ParseContext::kSlopBytes) {\n"
- " object = &msg->$1$_;\n"
- " parser_till_end = ::$proto_ns$::internal::GreedyStringParser$2$;\n"
- " goto arena_string_till_end;\n"
- "}\n"
- "$GOOGLE_PROTOBUF$_PARSER_ASSERT(::$proto_ns$::internal::StringCheck$2$"
- "(ptr, size, ctx));\n"
- "::$proto_ns$::internal::CopyIntoArenaString(ptr, size, &msg->$1$_, "
- "msg->GetArenaNoVirtual());\n"
- "ptr += size;\n",
- FieldName(field), utf8);
+ "ptr = $pi_ns$::InlineCopyIntoArenaString$1$(&$2$_, ptr, ctx, "
+ "GetArenaNoVirtual()$3$);\n",
+ utf8, FieldName(field), field_name);
}
void GenerateStrings(const FieldDescriptor* field, bool check_utf8) {
string utf8;
+ string field_name;
if (check_utf8) {
utf8 = GetUtf8Suffix(field, options_);
if (!utf8.empty()) {
- string name = "nullptr";
+ field_name = ", nullptr";
if (HasDescriptorMethods(field->file(), options_)) {
- name = "\"" + field->full_name() + "\"";
+ field_name = StrCat(", \"", field->full_name(), "\"");
}
- format_("ctx->extra_parse_data().SetFieldName($1$);\n", name);
}
}
FieldOptions::CType ctype = FieldOptions::STRING;
@@ -1523,73 +1460,40 @@
!IsProto1(field->file(), options_) &&
!IsStringInlined(field, options_) &&
field->containing_oneof() == nullptr && ctype == FieldOptions::STRING) {
- GenerateArenaString(field, utf8);
+ GenerateArenaString(field, utf8, field_name);
return;
}
- format_(
- "object = msg->$1$_$2$();\n"
- "if (size > end - ptr + "
- "::$proto_ns$::internal::ParseContext::kSlopBytes) {\n",
- field->is_repeated() && !field->is_packable() ? "add" : "mutable",
- FieldName(field));
string name;
- string label = "len_delim_till_end";
switch (ctype) {
case FieldOptions::STRING:
- name = "GreedyStringParser";
- use_string_ = true;
- label = "string_till_end";
+ name = "GreedyStringParser" + utf8;
break;
case FieldOptions::CORD:
- name = "CordParser";
- format_(" static_cast<::Cord*>(object)->Clear();\n");
+ name = "CordParser" + utf8;
break;
case FieldOptions::STRING_PIECE:
- name = "StringPieceParser";
- format_(
- " "
- "static_cast<::$proto_ns$::internal::StringPieceField*>(object)->"
- "Clear();\n");
+ name = "StringPieceParser" + utf8;
break;
}
format_(
- " parser_till_end = ::$proto_ns$::internal::$1$$2$;\n"
- " goto $3$;\n"
- "}\n"
- "$GOOGLE_PROTOBUF$_PARSER_ASSERT(::$proto_ns$::internal::StringCheck$2$"
- "(ptr, size, ctx));\n"
- "::$proto_ns$::internal::Inline$1$(object, ptr, size, ctx);\n"
- "ptr += size;\n",
- name, utf8, label);
+ "ptr = $pi_ns$::Inline$1$($2$_$3$(), ptr, ctx$4$);\n",
+ name, field->is_repeated() && !field->is_packable() ? "add" : "mutable",
+ FieldName(field), field_name);
}
void GenerateLengthDelim(const FieldDescriptor* field) {
- format_(
- "ptr = ::$proto_ns$::io::ReadSize(ptr, &size);\n"
- "$GOOGLE_PROTOBUF$_PARSER_ASSERT(ptr);\n");
if (!IsProto1(field->file(), options_) && field->is_packable()) {
+ string enum_validator;
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));
+ enum_validator = StrCat(
+ ", ", QualifiedClassName(field->enum_type()),
+ "_IsValid, mutable_unknown_fields(), ", field->number());
}
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");
+ "ptr = $pi_ns$::Packed$1$Parser(mutable_$2$(), ptr, ctx$3$);\n",
+ DeclaredTypeMethodName(field->type()), FieldName(field),
+ enum_validator);
} else {
auto field_type = field->type();
if (IsProto1(field->file(), options_)) {
@@ -1610,106 +1514,62 @@
GenerateStrings(field, false /* utf8 */);
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 (!IsProto1(field->file(), options_) && IsLazy(field, options_)) {
+ format_("ptr = ctx->ParseMessage(&$1$_, ptr);\n", FieldName(field));
+ } else if (!IsProto1(field->file(), options_) &&
+ IsLazy(field, options_)) {
if (field->containing_oneof() != nullptr) {
format_(
- "if (!msg->has_$1$()) {\n"
- " msg->clear_$1$();\n"
- " msg->$2$_.$1$_ = ::$proto_ns$::Arena::CreateMessage<\n"
- " ::$proto_ns$::internal::LazyField>("
- "msg->GetArenaNoVirtual());\n"
- " msg->set_has_$1$();\n"
+ "if (!has_$1$()) {\n"
+ " clear_$1$();\n"
+ " $2$_.$1$_ = ::$proto_ns$::Arena::CreateMessage<\n"
+ " $pi_ns$::LazyField>("
+ "GetArenaNoVirtual());\n"
+ " set_has_$1$();\n"
"}\n"
- "auto parse_closure = msg->$2$_.$1$_->_ParseClosure();\n",
+ "ptr = ctx->ParseMessage($2$_.$1$_, ptr);\n",
FieldName(field), field->containing_oneof()->name());
} else if (HasFieldPresence(field->file())) {
format_(
- "HasBitSetters::set_has_$1$(msg);\n"
- "auto parse_closure = msg->$1$_._ParseClosure();\n",
+ "HasBitSetters::set_has_$1$(this);\n"
+ "ptr = ctx->ParseMessage(&$1$_, ptr);\n",
FieldName(field));
} else {
- format_("auto parse_closure = msg->$1$_._ParseClosure();\n",
- FieldName(field));
+ format_(
+ "ptr = ctx->ParseMessage(&$1$_, ptr);\n", FieldName(field));
}
- format_(
- "parser_till_end = parse_closure.func;\n"
- "object = parse_closure.object;\n"
- "if (size > end - ptr) goto len_delim_till_end;\n"
- "auto newend = ptr + size;\n"
- "$GOOGLE_PROTOBUF$_PARSER_ASSERT(ctx->ParseExactRange(\n"
- " parse_closure, ptr, newend));\n"
- "ptr = newend;\n");
- break;
- }
- if (IsImplicitWeakField(field, options_, scc_analyzer_)) {
+ } else if (IsImplicitWeakField(field, options_, scc_analyzer_)) {
if (!field->is_repeated()) {
- format_("object = HasBitSetters::mutable_$1$(msg);\n",
- FieldName(field));
+ format_(
+ "ptr = ctx->ParseMessage(HasBitSetters::mutable_$1$(this), "
+ "ptr);\n",
+ FieldName(field));
} else {
format_(
- "object = "
- "CastToBase(&msg->$1$_)->AddWeak(reinterpret_cast<const "
- "::$proto_ns$::MessageLite*>(&$2$::_$3$_default_instance_));"
- "\n",
+ "ptr = ctx->ParseMessage("
+ "CastToBase(&$1$_)->AddWeak(reinterpret_cast<const "
+ "::$proto_ns$::MessageLite*>(&$2$::_$3$_default_instance_)), "
+ "ptr);\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));
+ format_(
+ "ptr = ctx->ParseMessage("
+ "reinterpret_cast<$p_ns$::MessageLite*>(internal_mutable_$1$("
+ ")), ptr);\n",
+ FieldName(field));
} else {
format_(
- "object = msg->_weak_field_map_.MutableMessage($1$, "
- "_$classname$_default_instance_.$2$_);\n",
+ "ptr = ctx->ParseMessage(_weak_field_map_.MutableMessage($1$,"
+ " _$classname$_default_instance_.$2$_), ptr);\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_("ptr = ctx->ParseMessage($1$_$2$(), ptr);\n",
+ field->is_repeated() ? "add" : "mutable", FieldName(field));
}
- format_(
- "if (size > end - ptr) goto len_delim_till_end;\n"
- "ptr += size;\n"
- "$GOOGLE_PROTOBUF$_PARSER_ASSERT(ctx->ParseExactRange(\n"
- " {parser_till_end, object}, ptr - size, ptr));\n");
break;
}
default:
@@ -1731,31 +1591,33 @@
string prefix = field->is_repeated() ? "add" : "set";
if (field->type() == FieldDescriptor::TYPE_ENUM &&
!IsProto1(field->file(), options_)) {
- format_("$uint64$ val = ::$proto_ns$::internal::ReadVarint(&ptr);\n");
+ format_(
+ "$uint64$ val = $pi_ns$::ReadVarint(&ptr);\n"
+ "$GOOGLE_PROTOBUF$_PARSER_ASSERT(ptr);\n");
if (!HasPreservingUnknownEnumSemantics(field->file())) {
format_(
"if (!$1$_IsValid(val)) {\n"
- " ::$proto_ns$::internal::WriteVarint($2$, val, "
- "msg->mutable_unknown_fields());\n"
+ " $pi_ns$::WriteVarint($2$, val, "
+ "mutable_unknown_fields());\n"
" break;\n"
"}\n",
QualifiedClassName(field->enum_type()), field->number());
}
- format_("msg->$1$_$2$(static_cast<$3$>(val));\n", prefix,
- FieldName(field), QualifiedClassName(field->enum_type()));
+ format_("$1$_$2$(static_cast<$3$>(val));\n", prefix, FieldName(field),
+ QualifiedClassName(field->enum_type()));
} else {
+ int size = field->type() == FieldDescriptor::TYPE_SINT32 ? 32 : 64;
string zigzag;
if ((field->type() == FieldDescriptor::TYPE_SINT32 ||
field->type() == FieldDescriptor::TYPE_SINT64) &&
!IsProto1(field->file(), options_)) {
- int size = field->type() == FieldDescriptor::TYPE_SINT32 ? 32 : 64;
zigzag = StrCat("ZigZag", size);
}
format_(
- "msg->$1$_$2$(::$proto_ns$::internal::ReadVarint$3$(&ptr));\n",
+ "$1$_$2$($pi_ns$::ReadVarint$3$(&ptr));\n"
+ "$GOOGLE_PROTOBUF$_PARSER_ASSERT(ptr);\n",
prefix, FieldName(field), zigzag);
}
- format_("$GOOGLE_PROTOBUF$_PARSER_ASSERT(ptr);\n");
break;
}
case WireFormatLite::WIRETYPE_FIXED32:
@@ -1763,28 +1625,20 @@
string prefix = field->is_repeated() ? "add" : "set";
string type = PrimitiveTypeName(options_, field->cpp_type());
format_(
- "msg->$1$_$2$(::$proto_ns$::io::UnalignedLoad<$3$>(ptr));\n"
+ "$1$_$2$($pi_ns$::UnalignedLoad<$3$>(ptr));\n"
"ptr += sizeof($3$);\n",
prefix, FieldName(field), type);
break;
}
case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
- use_length_delimited_ = true;
GenerateLengthDelim(field);
+ format_("$GOOGLE_PROTOBUF$_PARSER_ASSERT(ptr);\n");
break;
}
case WireFormatLite::WIRETYPE_START_GROUP: {
- use_group_ = true;
format_(
- "parser_till_end = $1$::_InternalParse;\n"
- "object = msg->$2$_$3$();\n"
- "auto res = ctx->ParseGroup(tag, {parser_till_end, object}, ptr, "
- "end, "
- "&depth);\n"
- "ptr = res.first;\n"
- "$GOOGLE_PROTOBUF$_PARSER_ASSERT(ptr);\n"
- "if (res.second) goto group_continues;\n",
- QualifiedClassName(field->message_type()),
+ "ptr = ctx->ParseGroup($1$_$2$(), ptr, tag);\n"
+ "$GOOGLE_PROTOBUF$_PARSER_ASSERT(ptr);\n",
field->is_repeated() ? "add" : "mutable", FieldName(field));
break;
}
@@ -1795,7 +1649,6 @@
} // switch (wire_type)
if (ShouldRepeat(field, wiretype)) {
- format_("if (ptr >= end) break;\n");
uint32 x = field->number() * 8 + wiretype;
uint64 y = 0;
int cnt = 0;
@@ -1805,10 +1658,11 @@
x >>= 7;
} while (x);
uint64 mask = (1ull << (cnt * 8)) - 1;
+ format_("if (ctx->Done(&ptr)) return ptr;\n");
format_.Outdent();
format_(
- "} while ((::$proto_ns$::io::UnalignedLoad<$uint64$>(ptr) & $1$) == "
- "$2$ && (ptr += $3$));\n",
+ "} while (($pi_ns$::UnalignedLoad<$uint64$>(ptr)"
+ " & $1$) == $2$ && (ptr += $3$));\n",
mask, y, cnt);
}
format_("break;\n");
diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
index 86e4df3..bc9ca92 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
@@ -65,15 +65,15 @@
switch (val->cpp_type()) {
case FieldDescriptor::CPPTYPE_MESSAGE:
(*variables)["val_cpp"] = FieldMessageTypeName(val);
- (*variables)["wrapper"] = "EntryWrapper";
+ (*variables)["wrapper"] = "MapEntryWrapper";
break;
case FieldDescriptor::CPPTYPE_ENUM:
(*variables)["val_cpp"] = ClassName(val->enum_type(), true);
- (*variables)["wrapper"] = "EnumEntryWrapper";
+ (*variables)["wrapper"] = "MapEnumEntryWrapper";
break;
default:
(*variables)["val_cpp"] = PrimitiveTypeName(options, val->cpp_type());
- (*variables)["wrapper"] = "EntryWrapper";
+ (*variables)["wrapper"] = "MapEntryWrapper";
}
(*variables)["key_wire_type"] =
"TYPE_" + ToUpper(DeclaredTypeMethodName(key->type()));
@@ -238,11 +238,9 @@
}
}
-static void GenerateSerializationLoop(const Formatter& format,
- bool supports_arenas, bool string_key,
+static void GenerateSerializationLoop(const Formatter& format, bool string_key,
bool string_value, bool to_array,
bool is_deterministic) {
- format("::std::unique_ptr<$map_classname$> entry;\n");
string ptr;
if (is_deterministic) {
format("for (size_type i = 0; i < n; i++) {\n");
@@ -257,24 +255,17 @@
}
format.Indent();
- format("entry.reset($name$_.New$wrapper$($1$->first, $1$->second));\n", ptr);
+ format(
+ "$map_classname$::$wrapper$ entry(nullptr, $1$->first, $1$->second);\n",
+ ptr);
if (to_array) {
format(
"target = ::$proto_ns$::internal::WireFormatLite::InternalWrite"
- "$declared_type$NoVirtualToArray($number$, *entry, target);\n");
+ "$declared_type$NoVirtualToArray($number$, entry, target);\n");
} else {
format(
"::$proto_ns$::internal::WireFormatLite::Write$stream_writer$($number$,"
- " "
- "*entry, output);\n");
- }
-
- // If entry is allocated by arena, its desctructor should be avoided.
- if (supports_arenas) {
- format(
- "if (entry->GetArena() != nullptr) {\n"
- " entry.release();\n"
- "}\n");
+ " entry, output);\n");
}
if (string_key || string_value) {
@@ -365,13 +356,11 @@
" ::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less());\n",
to_array ? "false" : "output->IsSerializationDeterministic()");
format.Indent();
- GenerateSerializationLoop(format, SupportsArenas(descriptor_), string_key,
- string_value, to_array, true);
+ GenerateSerializationLoop(format, string_key, string_value, to_array, true);
format.Outdent();
format("} else {\n");
format.Indent();
- GenerateSerializationLoop(format, SupportsArenas(descriptor_), string_key,
- string_value, to_array, false);
+ GenerateSerializationLoop(format, string_key, string_value, to_array, false);
format.Outdent();
format("}\n");
format.Outdent();
@@ -384,35 +373,13 @@
format(
"total_size += $tag_size$ *\n"
" ::$proto_ns$::internal::FromIntSize(this->$name$_size());\n"
- "{\n"
- " ::std::unique_ptr<$map_classname$> entry;\n"
- " for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
- " it = this->$name$().begin();\n"
- " it != this->$name$().end(); ++it) {\n");
-
- // If entry is allocated by arena, its desctructor should be avoided.
- if (SupportsArenas(descriptor_)) {
- format(
- " if (entry.get() != nullptr && entry->GetArena() != nullptr) {\n"
- " entry.release();\n"
- " }\n");
- }
-
- format(
- " entry.reset($name$_.New$wrapper$(it->first, it->second));\n"
- " total_size += ::$proto_ns$::internal::WireFormatLite::\n"
- " $declared_type$SizeNoVirtual(*entry);\n"
- " }\n");
-
- // If entry is allocated by arena, its desctructor should be avoided.
- if (SupportsArenas(descriptor_)) {
- format(
- " if (entry.get() != nullptr && entry->GetArena() != nullptr) {\n"
- " entry.release();\n"
- " }\n");
- }
-
- format("}\n");
+ "for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
+ " it = this->$name$().begin();\n"
+ " it != this->$name$().end(); ++it) {\n"
+ " $map_classname$::$wrapper$ entry(nullptr, it->first, it->second);\n"
+ " total_size += ::$proto_ns$::internal::WireFormatLite::\n"
+ " $declared_type$SizeNoVirtual(entry);\n"
+ "}\n");
}
} // namespace cpp
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index ed20edd..01ab53e 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -948,10 +948,6 @@
" ::$proto_ns$::internal::WireFormatLite::$val_wire_type$,\n"
" $default_enum_value$ > {\n"
"public:\n"
- "#if $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n"
- "static bool _ParseMap(const char* begin, const "
- "char* end, void* object, ::$proto_ns$::internal::ParseContext* ctx);\n"
- "#endif // $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n"
" typedef ::$proto_ns$::internal::MapEntry$lite$<$classname$, \n"
" $key_cpp$, $val_cpp$,\n"
" ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
@@ -1097,20 +1093,39 @@
if (IsAnyMessage(descriptor_, options_)) {
format(
"// implements Any -----------------------------------------------\n"
- "\n"
- "void PackFrom(const ::$proto_ns$::Message& message);\n"
- "void PackFrom(const ::$proto_ns$::Message& message,\n"
- " const $string$& type_url_prefix);\n"
- "bool UnpackTo(::$proto_ns$::Message* message) const;\n"
+ "\n");
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ format(
+ "void PackFrom(const ::$proto_ns$::Message& message);\n"
+ "void PackFrom(const ::$proto_ns$::Message& message,\n"
+ " const $string$& type_url_prefix);\n"
+ "bool UnpackTo(::$proto_ns$::Message* message) const;\n"
+ "static bool GetAnyFieldDescriptors(\n"
+ " const ::$proto_ns$::Message& message,\n"
+ " const ::$proto_ns$::FieldDescriptor** type_url_field,\n"
+ " const ::$proto_ns$::FieldDescriptor** value_field);\n");
+ } else {
+ format(
+ "template <typename T>\n"
+ "void PackFrom(const T& message) {\n"
+ " _any_metadata_.PackFrom(message);\n"
+ "}\n"
+ "template <typename T>\n"
+ "void PackFrom(const T& message,\n"
+ " const $string$& type_url_prefix) {\n"
+ " _any_metadata_.PackFrom(message, type_url_prefix);"
+ "}\n"
+ "template <typename T>\n"
+ "bool UnpackTo(T* message) const {\n"
+ " return _any_metadata_.UnpackTo(message);\n"
+ "}\n");
+ }
+ format(
"template<typename T> bool Is() const {\n"
" return _any_metadata_.Is<T>();\n"
"}\n"
"static bool ParseAnyTypeUrl(const string& type_url,\n"
- " string* full_type_name);\n"
- "static bool GetAnyFieldDescriptors(\n"
- " const ::$proto_ns$::Message& message,\n"
- " const ::$proto_ns$::FieldDescriptor** type_url_field,\n"
- " const ::$proto_ns$::FieldDescriptor** value_field);\n");
+ " string* full_type_name);\n");
}
format.Set("new_final",
@@ -1166,24 +1181,13 @@
"\n"
"size_t ByteSizeLong() const final;\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"
- "::$proto_ns$::internal::ParseFunc _ParseFunc() const final { return "
- "_InternalParse; }\n"
+ "const char* _InternalParse(const char* ptr, "
+ "::$proto_ns$::internal::ParseContext* ctx) final;\n"
"#else\n"
"bool MergePartialFromCodedStream(\n"
" ::$proto_ns$::io::CodedInputStream* input)$ "
"merge_partial_final$;\n"
"#endif // $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n");
- if (descriptor_->options().message_set_wire_format()) {
- format(
- "#if $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n"
- "static const char* InternalParseMessageSetItem(const char* begin, "
- "const char* end, void* object, "
- "::$proto_ns$::internal::ParseContext* "
- "ctx);\n"
- "#endif // $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n");
- }
if (!options_.table_driven_serialization ||
descriptor_->options().message_set_wire_format()) {
@@ -1206,10 +1210,20 @@
format(
"int GetCachedSize() const final { return _cached_size_.Get(); }"
"\n\nprivate:\n"
- "void SharedCtor();\n"
- "void SharedDtor();\n"
+ "inline void SharedCtor();\n"
+ "inline void SharedDtor();\n"
"void SetCachedSize(int size) const$ full_final$;\n"
"void InternalSwap($classname$* other);\n");
+
+ format(
+ // Friend AnyMetadata so that it can call this FullMessageName() method.
+ "friend class ::$proto_ns$::internal::AnyMetadata;\n"
+ "static $1$ FullMessageName() {\n"
+ " return \"$full_name$\";\n"
+ "}\n",
+ options_.opensource_runtime ? "::google::protobuf::StringPiece"
+ : "::StringPiece");
+
if (SupportsArenas(descriptor_)) {
format(
// TODO(gerbens) Make this private! Currently people are deriving from
@@ -1871,65 +1885,6 @@
"}\n"
"\n");
}
- format(
- "#if $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n"
- "bool $classname$::_ParseMap(const char* begin, const char* end, "
- "void* object, ::$proto_ns$::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<::$proto_ns$::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;
}
@@ -1942,31 +1897,34 @@
format("}\n");
if (IsAnyMessage(descriptor_, options_)) {
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ format(
+ "void $classname$::PackFrom(const ::$proto_ns$::Message& message) {\n"
+ " _any_metadata_.PackFrom(message);\n"
+ "}\n"
+ "\n"
+ "void $classname$::PackFrom(const ::$proto_ns$::Message& message,\n"
+ " const $string$& type_url_prefix) {\n"
+ " _any_metadata_.PackFrom(message, type_url_prefix);\n"
+ "}\n"
+ "\n"
+ "bool $classname$::UnpackTo(::$proto_ns$::Message* message) const {\n"
+ " return _any_metadata_.UnpackTo(message);\n"
+ "}\n"
+ "bool $classname$::GetAnyFieldDescriptors(\n"
+ " const ::$proto_ns$::Message& message,\n"
+ " const ::$proto_ns$::FieldDescriptor** type_url_field,\n"
+ " const ::$proto_ns$::FieldDescriptor** value_field) {\n"
+ " return ::$proto_ns$::internal::GetAnyFieldDescriptors(\n"
+ " message, type_url_field, value_field);\n"
+ "}\n");
+ }
format(
- "void $classname$::PackFrom(const ::$proto_ns$::Message& message) {\n"
- " _any_metadata_.PackFrom(message);\n"
- "}\n"
- "\n"
- "void $classname$::PackFrom(const ::$proto_ns$::Message& message,\n"
- " const $string$& type_url_prefix) {\n"
- " _any_metadata_.PackFrom(message, type_url_prefix);\n"
- "}\n"
- "\n"
- "bool $classname$::UnpackTo(::$proto_ns$::Message* message) const {\n"
- " return _any_metadata_.UnpackTo(message);\n"
- "}\n"
"bool $classname$::ParseAnyTypeUrl(const string& type_url,\n"
" string* full_type_name) {\n"
" return ::$proto_ns$::internal::ParseAnyTypeUrl(type_url,\n"
" full_type_name);\n"
"}\n"
- "bool $classname$::GetAnyFieldDescriptors(\n"
- " const ::$proto_ns$::Message& message,\n"
- " const ::$proto_ns$::FieldDescriptor** type_url_field,\n"
- " const ::$proto_ns$::FieldDescriptor** value_field) {\n"
- " return ::$proto_ns$::internal::GetAnyFieldDescriptors(\n"
- " message, type_url_field, value_field);\n"
- "}\n"
"\n");
}
@@ -3360,21 +3318,10 @@
// Special-case MessageSet.
format(
"#if $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n"
- "const char* $classname$::_InternalParse(const char* begin, const "
- "char* end, void* object,\n"
+ "const char* $classname$::_InternalParse(const char* ptr,\n"
" ::$proto_ns$::internal::ParseContext* ctx) {\n"
- " auto msg = static_cast<$classname$*>(object);\n"
- " return ::$proto_ns$::internal::ParseMessageSet(begin, end, "
- "msg, &msg->_extensions_, &msg->_internal_metadata_, ctx);\n"
- "}\n"
- "const char* $classname$::InternalParseMessageSetItem(const char* "
- "begin, const char* end, void* object,\n"
- " ::$proto_ns$::internal::ParseContext* ctx) {\n"
- " auto msg = static_cast<$classname$*>(object);\n"
- " return "
- "msg->_extensions_.ParseMessageSetItem({InternalParseMessageSetItem, "
- "msg}, begin, end, internal_default_instance(), "
- "&msg->_internal_metadata_, ctx);\n"
+ " return _extensions_.ParseMessageSet(ptr, \n"
+ " internal_default_instance(), &_internal_metadata_, ctx);\n"
"}\n"
"#else\n"
"bool $classname$::MergePartialFromCodedStream(\n"
diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc
index 35c9a31..6517e5b 100644
--- a/src/google/protobuf/compiler/java/java_enum_field.cc
+++ b/src/google/protobuf/compiler/java/java_enum_field.cc
@@ -152,11 +152,11 @@
ImmutableEnumFieldGenerator::~ImmutableEnumFieldGenerator() {}
int ImmutableEnumFieldGenerator::GetNumBitsForMessage() const {
- return 1;
+ return SupportFieldPresence(descriptor_->file()) ? 1 : 0;
}
int ImmutableEnumFieldGenerator::GetNumBitsForBuilder() const {
- return 1;
+ return GetNumBitsForMessage();
}
void ImmutableEnumFieldGenerator::
diff --git a/src/google/protobuf/compiler/java/java_enum_field_lite.cc b/src/google/protobuf/compiler/java/java_enum_field_lite.cc
index 2b0ec29..458bf3d 100644
--- a/src/google/protobuf/compiler/java/java_enum_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_enum_field_lite.cc
@@ -132,7 +132,7 @@
ImmutableEnumFieldLiteGenerator::~ImmutableEnumFieldLiteGenerator() {}
int ImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const {
- return 1;
+ return SupportFieldPresence(descriptor_->file()) ? 1 : 0;
}
void ImmutableEnumFieldLiteGenerator::
diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc
index 9aabd62..c60e8c5 100644
--- a/src/google/protobuf/compiler/java/java_message.cc
+++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -66,11 +66,6 @@
using internal::WireFormatLite;
namespace {
-bool GenerateHasBits(const Descriptor* descriptor) {
- return SupportFieldPresence(descriptor->file()) ||
- HasRepeatedFields(descriptor);
-}
-
string MapValueImmutableClassdName(const Descriptor* descriptor,
ClassNameResolver* name_resolver) {
const FieldDescriptor* value_field = descriptor->FindFieldByName("value");
@@ -397,18 +392,16 @@
messageGenerator.Generate(printer);
}
- if (GenerateHasBits(descriptor_)) {
- // Integers for bit fields.
- int totalBits = 0;
- for (int i = 0; i < descriptor_->field_count(); i++) {
- totalBits += field_generators_.get(descriptor_->field(i))
- .GetNumBitsForMessage();
- }
- int totalInts = (totalBits + 31) / 32;
- for (int i = 0; i < totalInts; i++) {
- printer->Print("private int $bit_field_name$;\n",
- "bit_field_name", GetBitFieldName(i));
- }
+ // Integers for bit fields.
+ int totalBits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ totalBits +=
+ field_generators_.get(descriptor_->field(i)).GetNumBitsForMessage();
+ }
+ int totalInts = (totalBits + 31) / 32;
+ for (int i = 0; i < totalInts; i++) {
+ printer->Print("private int $bit_field_name$;\n", "bit_field_name",
+ GetBitFieldName(i));
}
// oneof
diff --git a/src/google/protobuf/compiler/java/java_message_builder.cc b/src/google/protobuf/compiler/java/java_message_builder.cc
index 761be79..b78f1e7 100644
--- a/src/google/protobuf/compiler/java/java_message_builder.cc
+++ b/src/google/protobuf/compiler/java/java_message_builder.cc
@@ -61,11 +61,6 @@
namespace java {
namespace {
-bool GenerateHasBits(const Descriptor* descriptor) {
- return SupportFieldPresence(descriptor->file()) ||
- HasRepeatedFields(descriptor);
-}
-
string MapValueImmutableClassdName(const Descriptor* descriptor,
ClassNameResolver* name_resolver) {
const FieldDescriptor* value_field = descriptor->FindFieldByName("value");
@@ -149,18 +144,16 @@
"\n");
}
- if (GenerateHasBits(descriptor_)) {
- // Integers for bit fields.
- int totalBits = 0;
- for (int i = 0; i < descriptor_->field_count(); i++) {
- totalBits += field_generators_.get(descriptor_->field(i))
- .GetNumBitsForBuilder();
- }
- int totalInts = (totalBits + 31) / 32;
- for (int i = 0; i < totalInts; i++) {
- printer->Print("private int $bit_field_name$;\n",
- "bit_field_name", GetBitFieldName(i));
- }
+ // Integers for bit fields.
+ int totalBits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ totalBits +=
+ field_generators_.get(descriptor_->field(i)).GetNumBitsForBuilder();
+ }
+ int totalInts = (totalBits + 31) / 32;
+ for (int i = 0; i < totalInts; i++) {
+ printer->Print("private int $bit_field_name$;\n", "bit_field_name",
+ GetBitFieldName(i));
}
for (int i = 0; i < descriptor_->field_count(); i++) {
@@ -408,19 +401,17 @@
int totalBuilderInts = (totalBuilderBits + 31) / 32;
int totalMessageInts = (totalMessageBits + 31) / 32;
- if (GenerateHasBits(descriptor_)) {
- // Local vars for from and to bit fields to avoid accessing the builder and
- // message over and over for these fields. Seems to provide a slight
- // perforamance improvement in micro benchmark and this is also what proto1
- // code does.
- for (int i = 0; i < totalBuilderInts; i++) {
- printer->Print("int from_$bit_field_name$ = $bit_field_name$;\n",
- "bit_field_name", GetBitFieldName(i));
- }
- for (int i = 0; i < totalMessageInts; i++) {
- printer->Print("int to_$bit_field_name$ = 0;\n",
- "bit_field_name", GetBitFieldName(i));
- }
+ // Local vars for from and to bit fields to avoid accessing the builder and
+ // message over and over for these fields. Seems to provide a slight
+ // perforamance improvement in micro benchmark and this is also what proto1
+ // code does.
+ for (int i = 0; i < totalBuilderInts; i++) {
+ printer->Print("int from_$bit_field_name$ = $bit_field_name$;\n",
+ "bit_field_name", GetBitFieldName(i));
+ }
+ for (int i = 0; i < totalMessageInts; i++) {
+ printer->Print("int to_$bit_field_name$ = 0;\n", "bit_field_name",
+ GetBitFieldName(i));
}
// Output generation code for each field.
@@ -428,12 +419,10 @@
field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer);
}
- if (GenerateHasBits(descriptor_)) {
- // Copy the bit field results to the generated message
- for (int i = 0; i < totalMessageInts; i++) {
- printer->Print("result.$bit_field_name$ = to_$bit_field_name$;\n",
- "bit_field_name", GetBitFieldName(i));
- }
+ // Copy the bit field results to the generated message
+ for (int i = 0; i < totalMessageInts; i++) {
+ printer->Print("result.$bit_field_name$ = to_$bit_field_name$;\n",
+ "bit_field_name", GetBitFieldName(i));
}
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
diff --git a/src/google/protobuf/compiler/java/java_message_builder_lite.cc b/src/google/protobuf/compiler/java/java_message_builder_lite.cc
index 8987fa4..641f66a 100644
--- a/src/google/protobuf/compiler/java/java_message_builder_lite.cc
+++ b/src/google/protobuf/compiler/java/java_message_builder_lite.cc
@@ -59,13 +59,6 @@
namespace compiler {
namespace java {
-namespace {
-bool GenerateHasBits(const Descriptor* descriptor) {
- return SupportFieldPresence(descriptor->file()) ||
- HasRepeatedFields(descriptor);
-}
-} // namespace
-
MessageBuilderLiteGenerator::MessageBuilderLiteGenerator(
const Descriptor* descriptor, Context* context)
: descriptor_(descriptor), context_(context),
diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc
index 5b6de09..d79b8c4 100644
--- a/src/google/protobuf/compiler/java/java_message_field.cc
+++ b/src/google/protobuf/compiler/java/java_message_field.cc
@@ -137,11 +137,11 @@
ImmutableMessageFieldGenerator::~ImmutableMessageFieldGenerator() {}
int ImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
- return 1;
+ return SupportFieldPresence(descriptor_->file()) ? 1 : 0;
}
int ImmutableMessageFieldGenerator::GetNumBitsForBuilder() const {
- return 1;
+ return GetNumBitsForMessage();
}
void ImmutableMessageFieldGenerator::
diff --git a/src/google/protobuf/compiler/java/java_message_field_lite.cc b/src/google/protobuf/compiler/java/java_message_field_lite.cc
index 58fbf15..8501203 100644
--- a/src/google/protobuf/compiler/java/java_message_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_message_field_lite.cc
@@ -119,7 +119,7 @@
ImmutableMessageFieldLiteGenerator::~ImmutableMessageFieldLiteGenerator() {}
int ImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const {
- return 1;
+ return SupportFieldPresence(descriptor_->file()) ? 1 : 0;
}
void ImmutableMessageFieldLiteGenerator::
diff --git a/src/google/protobuf/compiler/java/java_message_lite.cc b/src/google/protobuf/compiler/java/java_message_lite.cc
index 3f907e2..abc5101 100644
--- a/src/google/protobuf/compiler/java/java_message_lite.cc
+++ b/src/google/protobuf/compiler/java/java_message_lite.cc
@@ -74,11 +74,6 @@
#endif // !PROTOBUF_EXPERIMENT
}
-bool GenerateHasBits(const Descriptor* descriptor) {
- return SupportFieldPresence(descriptor->file()) ||
- HasRepeatedFields(descriptor);
-}
-
string MapValueImmutableClassdName(const Descriptor* descriptor,
ClassNameResolver* name_resolver) {
const FieldDescriptor* value_field = descriptor->FindFieldByName("value");
@@ -233,18 +228,16 @@
messageGenerator.Generate(printer);
}
- if (GenerateHasBits(descriptor_)) {
- // Integers for bit fields.
- int totalBits = 0;
- for (int i = 0; i < descriptor_->field_count(); i++) {
- totalBits += field_generators_.get(descriptor_->field(i))
- .GetNumBitsForMessage();
- }
- int totalInts = (totalBits + 31) / 32;
- for (int i = 0; i < totalInts; i++) {
- printer->Print("private int $bit_field_name$;\n",
- "bit_field_name", GetBitFieldName(i));
- }
+ // Integers for bit fields.
+ int totalBits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ totalBits +=
+ field_generators_.get(descriptor_->field(i)).GetNumBitsForMessage();
+ }
+ int totalInts = (totalBits + 31) / 32;
+ for (int i = 0; i < totalInts; i++) {
+ printer->Print("private int $bit_field_name$;\n", "bit_field_name",
+ GetBitFieldName(i));
}
// oneof
@@ -952,20 +945,17 @@
"oneof_name", context_->GetOneofGeneratorInfo(field)->name);
}
- if (GenerateHasBits(descriptor_)) {
- // Integers for bit fields.
- int totalBits = 0;
- for (int i = 0; i < descriptor_->field_count(); i++) {
- totalBits += field_generators_.get(descriptor_->field(i))
- .GetNumBitsForMessage();
- }
- int totalInts = (totalBits + 31) / 32;
+ // Integers for bit fields.
+ int totalBits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ totalBits +=
+ field_generators_.get(descriptor_->field(i)).GetNumBitsForMessage();
+ }
+ int totalInts = (totalBits + 31) / 32;
- for (int i = 0; i < totalInts; i++) {
- printer->Print(
- "$bit_field_name$ |= other.$bit_field_name$;\n",
- "bit_field_name", GetBitFieldName(i));
- }
+ for (int i = 0; i < totalInts; i++) {
+ printer->Print("$bit_field_name$ |= other.$bit_field_name$;\n",
+ "bit_field_name", GetBitFieldName(i));
}
printer->Outdent();
printer->Print(
diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc
index b3ab529..454e2eb 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field.cc
+++ b/src/google/protobuf/compiler/java/java_primitive_field.cc
@@ -201,11 +201,11 @@
ImmutablePrimitiveFieldGenerator::~ImmutablePrimitiveFieldGenerator() {}
int ImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const {
- return 1;
+ return SupportFieldPresence(descriptor_->file()) ? 1 : 0;
}
int ImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const {
- return 1;
+ return GetNumBitsForMessage();
}
void ImmutablePrimitiveFieldGenerator::
diff --git a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
index ce34882..2dfa242 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
@@ -187,7 +187,7 @@
ImmutablePrimitiveFieldLiteGenerator::~ImmutablePrimitiveFieldLiteGenerator() {}
int ImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const {
- return 1;
+ return SupportFieldPresence(descriptor_->file()) ? 1 : 0;
}
void ImmutablePrimitiveFieldLiteGenerator::
diff --git a/src/google/protobuf/compiler/java/java_service.cc b/src/google/protobuf/compiler/java/java_service.cc
index 36676f9..55c6eec 100644
--- a/src/google/protobuf/compiler/java/java_service.cc
+++ b/src/google/protobuf/compiler/java/java_service.cc
@@ -304,8 +304,10 @@
const MethodDescriptor* method = descriptor_->method(i);
std::map<string, string> vars;
vars["index"] = StrCat(i);
- vars["type"] = name_resolver_->GetImmutableClassName(
- (which == REQUEST) ? method->input_type() : method->output_type());
+ vars["type"] =
+ (which == REQUEST)
+ ? name_resolver_->GetImmutableClassName(method->input_type())
+ : GetOutput(method);
printer->Print(vars,
"case $index$:\n"
" return $type$.getDefaultInstance();\n");
diff --git a/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc
index 0184297..ac4cf1f 100644
--- a/src/google/protobuf/compiler/java/java_string_field.cc
+++ b/src/google/protobuf/compiler/java/java_string_field.cc
@@ -154,11 +154,11 @@
ImmutableStringFieldGenerator::~ImmutableStringFieldGenerator() {}
int ImmutableStringFieldGenerator::GetNumBitsForMessage() const {
- return 1;
+ return SupportFieldPresence(descriptor_->file()) ? 1 : 0;
}
int ImmutableStringFieldGenerator::GetNumBitsForBuilder() const {
- return 1;
+ return GetNumBitsForMessage();
}
// A note about how strings are handled. This code used to just store a String
diff --git a/src/google/protobuf/compiler/java/java_string_field_lite.cc b/src/google/protobuf/compiler/java/java_string_field_lite.cc
index 29f5d05..42c56f2 100644
--- a/src/google/protobuf/compiler/java/java_string_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_string_field_lite.cc
@@ -134,7 +134,7 @@
ImmutableStringFieldLiteGenerator::~ImmutableStringFieldLiteGenerator() {}
int ImmutableStringFieldLiteGenerator::GetNumBitsForMessage() const {
- return 1;
+ return SupportFieldPresence(descriptor_->file()) ? 1 : 0;
}
// A note about how strings are handled. In the SPEED and CODE_SIZE runtimes,
diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc
index 71e9ba8..c513a6e 100644
--- a/src/google/protobuf/compiler/js/js_generator.cc
+++ b/src/google/protobuf/compiler/js/js_generator.cc
@@ -1135,6 +1135,10 @@
string JSBinaryWriterMethodName(const GeneratorOptions& options,
const FieldDescriptor* field) {
+ if (field->containing_type() &&
+ field->containing_type()->options().message_set_wire_format()) {
+ return "jspb.BinaryWriter.prototype.writeMessageSet";
+ }
return "jspb.BinaryWriter.prototype.write" +
JSBinaryReadWriteMethodName(field, /* is_writer = */ true);
}
@@ -2243,17 +2247,17 @@
"\n"
"if (jspb.Message.GENERATE_TO_OBJECT) {\n"
"/**\n"
- " * Creates an object representation of this proto suitable for use in "
- "Soy templates.\n"
+ " * Creates an object representation of this proto.\n"
" * Field names that are reserved in JavaScript and will be renamed to "
"pb_name.\n"
+ " * Optional fields that are not set will be set to undefined.\n"
" * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.\n"
" * For the list of reserved names please see:\n"
- " * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.\n"
- " * @param {boolean=} opt_includeInstance Whether to include the JSPB "
- "instance\n"
- " * for transitional soy proto support: http://goto/soy-param-"
- "migration\n"
+ " * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n"
+ " * @param {boolean=} opt_includeInstance Deprecated. whether to include "
+ "the\n"
+ " * JSPB instance for transitional soy proto support:\n"
+ " * http://goto/soy-param-migration\n"
" * @return {!Object}\n"
" */\n"
"$classname$.prototype.toObject = function(opt_includeInstance) {\n"
@@ -2263,16 +2267,16 @@
"\n"
"/**\n"
" * Static version of the {@see toObject} method.\n"
- " * @param {boolean|undefined} includeInstance Whether to include the "
- "JSPB\n"
- " * instance for transitional soy proto support:\n"
+ " * @param {boolean|undefined} includeInstance Deprecated. Whether to "
+ "include\n"
+ " * the JSPB instance for transitional soy proto support:\n"
" * http://goto/soy-param-migration\n"
" * @param {!$classname$} msg The msg instance to transform.\n"
" * @return {!Object}\n"
" * @suppress {unusedLocalVariables} f is only used for nested messages\n"
" */\n"
"$classname$.toObject = function(includeInstance, msg) {\n"
- " var obj = {",
+ " var f, obj = {",
"classname", GetMessagePath(options, desc));
bool first = true;
@@ -2424,7 +2428,39 @@
// We are migrating the accessors to return defaults instead of null, but
// it may take longer to migrate toObject (or we might not want to do it at
// all). So we want to generate independent code.
+ // The accessor for unset optional values without default should return
+ // null. Those are converted to undefined in the generated object.
+ printer->Print("(f = ");
GenerateFieldValueExpression(printer, "msg", field, use_default);
+ printer->Print(") == null ? undefined : f");
+ }
+}
+
+void Generator::GenerateObjectTypedef(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ // TODO(b/122687752): Consider renaming nested messages called ObjectFormat
+ // to prevent collisions.
+ const string type_name = GetMessagePath(options, desc) + ".ObjectFormat";
+
+ printer->Print(
+ "/**\n"
+ " * The raw object form of $messageName$ as accepted by the `fromObject` "
+ "method.\n"
+ " * @record\n"
+ " */\n"
+ "$typeName$ = function() {};\n\n",
+ "messageName", desc->name(),
+ "typeName", type_name);
+
+ for (int i = 0; i < desc->field_count(); i++) {
+ printer->Print(
+ "/** @type {$fieldType$|undefined} */\n"
+ "$typeName$.prototype.$fieldName$;\n\n",
+ "typeName", type_name,
+ "fieldName", JSObjectFieldName(options, desc->field(i)),
+ // TODO(b/121097361): Add type checking for field values.
+ "fieldType", "?");
}
}
@@ -2432,15 +2468,16 @@
io::Printer* printer,
const Descriptor* desc) const {
printer->Print(
- "if (jspb.Message.GENERATE_FROM_OBJECT) {\n"
+ "if (jspb.Message.GENERATE_FROM_OBJECT) {\n\n");
+
+ GenerateObjectTypedef(options, printer, desc);
+
+ printer->Print(
"/**\n"
" * Loads data from an object into a new instance of this proto.\n"
- " * @param {!Object} obj The object representation of this proto to\n"
- " * load the data from.\n"
+ " * @param {!$classname$.ObjectFormat} obj\n"
+ " * The object representation of this proto to load the data from.\n"
" * @return {!$classname$}\n"
- " * @suppress {missingProperties} To prevent JSCompiler errors at "
- "the\n"
- " * `goog.isDef(obj.<fieldName>)` lookups.\n"
" */\n"
"$classname$.fromObject = function(obj) {\n"
" var msg = new $classname$();\n",
@@ -2456,7 +2493,7 @@
printer->Print(
" return msg;\n"
"};\n"
- "}\n");
+ "}\n\n");
}
void Generator::GenerateClassFieldFromObject(
@@ -2469,7 +2506,7 @@
// Since the map values are of message type, we have to do some extra work
// to recursively call fromObject() on them before setting the map field.
printer->Print(
- " goog.isDef(obj.$name$) && jspb.Message.setWrapperField(\n"
+ " obj.$name$ && jspb.Message.setWrapperField(\n"
" msg, $index$, jspb.Map.fromObject(obj.$name$, $fieldclass$, "
"$fieldclass$.fromObject));\n",
"name", JSObjectFieldName(options, field),
@@ -2480,7 +2517,7 @@
// map containers wrapping underlying arrays, so we can simply directly
// set the array here without fear of a stale wrapper.
printer->Print(
- " goog.isDef(obj.$name$) && "
+ " obj.$name$ && "
"jspb.Message.setField(msg, $index$, obj.$name$);\n",
"name", JSObjectFieldName(options, field),
"index", JSFieldIndex(field));
@@ -2490,7 +2527,7 @@
if (field->is_repeated()) {
{
printer->Print(
- " goog.isDef(obj.$name$) && "
+ " obj.$name$ && "
"jspb.Message.setRepeatedWrapperField(\n"
" msg, $index$, obj.$name$.map(\n"
" $fieldclass$.fromObject));\n",
@@ -2500,7 +2537,7 @@
}
} else {
printer->Print(
- " goog.isDef(obj.$name$) && jspb.Message.setWrapperField(\n"
+ " obj.$name$ && jspb.Message.setWrapperField(\n"
" msg, $index$, $fieldclass$.fromObject(obj.$name$));\n",
"name", JSObjectFieldName(options, field),
"index", JSFieldIndex(field),
@@ -2509,7 +2546,7 @@
} else {
// Simple (primitive) field.
printer->Print(
- " goog.isDef(obj.$name$) && jspb.Message.setField(msg, $index$, "
+ " obj.$name$ != null && jspb.Message.setField(msg, $index$, "
"obj.$name$);\n",
"name", JSObjectFieldName(options, field),
"index", JSFieldIndex(field));
diff --git a/src/google/protobuf/compiler/js/js_generator.h b/src/google/protobuf/compiler/js/js_generator.h
index a48750b..5af9b9f 100644
--- a/src/google/protobuf/compiler/js/js_generator.h
+++ b/src/google/protobuf/compiler/js/js_generator.h
@@ -272,6 +272,9 @@
void GenerateOneofCaseDefinition(const GeneratorOptions& options,
io::Printer* printer,
const OneofDescriptor* oneof) const;
+ void GenerateObjectTypedef(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
void GenerateClassToObject(const GeneratorOptions& options,
io::Printer* printer,
const Descriptor* desc) const;
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc
index 745271b..5877b9f 100644
--- a/src/google/protobuf/compiler/plugin.pb.cc
+++ b/src/google/protobuf/compiler/plugin.pb.cc
@@ -107,9 +107,9 @@
::google::protobuf::internal::InitSCC(&scc_info_CodeGeneratorResponse_google_2fprotobuf_2fcompiler_2fplugin_2eproto.base);
}
-::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[4];
-constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto = nullptr;
-constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto = nullptr;
+static ::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[4];
+static constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto = nullptr;
+static constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto = nullptr;
const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::Version, _has_bits_),
@@ -173,7 +173,7 @@
reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::compiler::_CodeGeneratorResponse_default_instance_),
};
-::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto = {
+static ::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto = {
{}, AddDescriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, "google/protobuf/compiler/plugin.proto", schemas,
file_default_instances, TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets,
file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto, 4, file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto,
@@ -197,7 +197,7 @@
"pilerB\014PluginProtosZ9github.com/golang/p"
"rotobuf/protoc-gen-go/plugin;plugin_go"
;
-::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto = {
+static ::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto = {
false, InitDefaults_google_2fprotobuf_2fcompiler_2fplugin_2eproto,
descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto,
"google/protobuf/compiler/plugin.proto", &assign_descriptors_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto, 638,
@@ -311,77 +311,54 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* Version::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<Version*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* Version::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional int32 major = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
- msg->set_major(::google::protobuf::internal::ReadVarint(&ptr));
+ set_major(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional int32 minor = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
- msg->set_minor(::google::protobuf::internal::ReadVarint(&ptr));
+ set_minor(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional int32 patch = 3;
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
- msg->set_patch(::google::protobuf::internal::ReadVarint(&ptr));
+ set_patch(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional string suffix = 4;
case 4: {
if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_suffix(), ptr, ctx, "google.protobuf.compiler.Version.suffix");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.Version.suffix");
- object = msg->mutable_suffix();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool Version::MergePartialFromCodedStream(
@@ -782,104 +759,60 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* CodeGeneratorRequest::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<CodeGeneratorRequest*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// repeated string file_to_generate = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(add_file_to_generate(), ptr, ctx, "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorRequest.file_to_generate");
- object = msg->add_file_to_generate();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
break;
}
// optional string parameter = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_parameter(), ptr, ctx, "google.protobuf.compiler.CodeGeneratorRequest.parameter");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorRequest.parameter");
- object = msg->mutable_parameter();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional .google.protobuf.compiler.Version compiler_version = 3;
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(mutable_compiler_version(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::compiler::Version::_InternalParse;
- object = msg->mutable_compiler_version();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
break;
}
// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
case 15: {
if (static_cast<::google::protobuf::uint8>(tag) != 122) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_proto_file(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::FileDescriptorProto::_InternalParse;
- object = msg->add_proto_file();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 122 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 122 && (ptr += 1));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool CodeGeneratorRequest::MergePartialFromCodedStream(
@@ -1295,88 +1228,47 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* CodeGeneratorResponse_File::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<CodeGeneratorResponse_File*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional string name = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_name(), ptr, ctx, "google.protobuf.compiler.CodeGeneratorResponse.File.name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorResponse.File.name");
- object = msg->mutable_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional string insertion_point = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_insertion_point(), ptr, ctx, "google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point");
- object = msg->mutable_insertion_point();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional string content = 15;
case 15: {
if (static_cast<::google::protobuf::uint8>(tag) != 122) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_content(), ptr, ctx, "google.protobuf.compiler.CodeGeneratorResponse.File.content");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorResponse.File.content");
- object = msg->mutable_content();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool CodeGeneratorResponse_File::MergePartialFromCodedStream(
@@ -1742,72 +1634,43 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* CodeGeneratorResponse::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<CodeGeneratorResponse*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* CodeGeneratorResponse::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional string error = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_error(), ptr, ctx, "google.protobuf.compiler.CodeGeneratorResponse.error");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorResponse.error");
- object = msg->mutable_error();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
case 15: {
if (static_cast<::google::protobuf::uint8>(tag) != 122) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_file(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::compiler::CodeGeneratorResponse_File::_InternalParse;
- object = msg->add_file();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 122 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 122 && (ptr += 1));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool CodeGeneratorResponse::MergePartialFromCodedStream(
diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h
index c84da10..0f7e8bb 100644
--- a/src/google/protobuf/compiler/plugin.pb.h
+++ b/src/google/protobuf/compiler/plugin.pb.h
@@ -31,6 +31,13 @@
#include <google/protobuf/repeated_field.h> // IWYU pragma: export
#include <google/protobuf/extension_set.h> // IWYU pragma: export
#include <google/protobuf/unknown_field_set.h>
+namespace google {
+namespace protobuf {
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+} // namespace protobuf
+} // namespace google
#include <google/protobuf/descriptor.pb.h>
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
@@ -153,8 +160,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -166,10 +172,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Version* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.compiler.Version";
+ }
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return nullptr;
@@ -306,8 +316,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -319,10 +328,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(CodeGeneratorRequest* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.compiler.CodeGeneratorRequest";
+ }
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return nullptr;
@@ -481,8 +494,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -494,10 +506,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(CodeGeneratorResponse_File* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.compiler.CodeGeneratorResponse.File";
+ }
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return nullptr;
@@ -642,8 +658,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -655,10 +670,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(CodeGeneratorResponse* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.compiler.CodeGeneratorResponse";
+ }
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return nullptr;
diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc
index 6b1e4d2..5009b24 100644
--- a/src/google/protobuf/compiler/python/python_generator.cc
+++ b/src/google/protobuf/compiler/python/python_generator.cc
@@ -814,7 +814,7 @@
void Generator::PrintMessages() const {
for (int i = 0; i < file_->message_type_count(); ++i) {
std::vector<string> to_register;
- PrintMessage(*file_->message_type(i), "", &to_register);
+ PrintMessage(*file_->message_type(i), "", &to_register, false);
for (int j = 0; j < to_register.size(); ++j) {
printer_->Print("_sym_db.RegisterMessage($name$)\n", "name",
to_register[j]);
@@ -833,25 +833,33 @@
// Collect nested message names to_register for the symbol_database.
void Generator::PrintMessage(const Descriptor& message_descriptor,
const string& prefix,
- std::vector<string>* to_register) const {
+ std::vector<string>* to_register,
+ bool is_nested) const {
string qualified_name(prefix + message_descriptor.name());
to_register->push_back(qualified_name);
- printer_->Print(
- "$name$ = _reflection.GeneratedProtocolMessageType('$name$', "
- "(_message.Message,), dict(\n",
- "name", message_descriptor.name());
+ if (is_nested) {
+ printer_->Print(
+ "'$name$' : _reflection.GeneratedProtocolMessageType('$name$', "
+ "(_message.Message,), {\n",
+ "name", message_descriptor.name());
+ } else {
+ printer_->Print(
+ "$name$ = _reflection.GeneratedProtocolMessageType('$name$', "
+ "(_message.Message,), {\n",
+ "name", message_descriptor.name());
+ }
printer_->Indent();
PrintNestedMessages(message_descriptor, qualified_name + ".", to_register);
std::map<string, string> m;
m["descriptor_key"] = kDescriptorKey;
m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor);
- printer_->Print(m, "$descriptor_key$ = $descriptor_name$,\n");
- printer_->Print("__module__ = '$module_name$'\n",
+ printer_->Print(m, "'$descriptor_key$' : $descriptor_name$,\n");
+ printer_->Print("'__module__' : '$module_name$'\n",
"module_name", ModuleName(file_->name()));
printer_->Print("# @@protoc_insertion_point(class_scope:$full_name$)\n",
"full_name", message_descriptor.full_name());
- printer_->Print("))\n");
+ printer_->Print("})\n");
printer_->Outdent();
}
@@ -862,7 +870,8 @@
std::vector<string>* to_register) const {
for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
printer_->Print("\n");
- PrintMessage(*containing_descriptor.nested_type(i), prefix, to_register);
+ PrintMessage(*containing_descriptor.nested_type(i), prefix, to_register,
+ true);
printer_->Print(",\n");
}
}
diff --git a/src/google/protobuf/compiler/python/python_generator.h b/src/google/protobuf/compiler/python/python_generator.h
index e90ff74..61f0385 100644
--- a/src/google/protobuf/compiler/python/python_generator.h
+++ b/src/google/protobuf/compiler/python/python_generator.h
@@ -98,7 +98,7 @@
void PrintMessages() const;
void PrintMessage(const Descriptor& message_descriptor, const std::string& prefix,
- std::vector<std::string>* to_register) const;
+ std::vector<std::string>* to_register, bool is_nested) const;
void PrintNestedMessages(const Descriptor& containing_descriptor,
const std::string& prefix,
std::vector<std::string>* to_register) const;
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index b999c1c..59321e9 100644
--- a/src/google/protobuf/descriptor.pb.cc
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -596,9 +596,9 @@
::google::protobuf::internal::InitSCC(&scc_info_GeneratedCodeInfo_google_2fprotobuf_2fdescriptor_2eproto.base);
}
-::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[27];
-const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[6];
-constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fdescriptor_2eproto = nullptr;
+static ::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[27];
+static const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[6];
+static constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fdescriptor_2eproto = nullptr;
const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2fdescriptor_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorSet, _has_bits_),
@@ -1045,7 +1045,7 @@
reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_GeneratedCodeInfo_default_instance_),
};
-::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto = {
+static ::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto = {
{}, AddDescriptors_google_2fprotobuf_2fdescriptor_2eproto, "google/protobuf/descriptor.proto", schemas,
file_default_instances, TableStruct_google_2fprotobuf_2fdescriptor_2eproto::offsets,
file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto, 27, file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto, file_level_service_descriptors_google_2fprotobuf_2fdescriptor_2eproto,
@@ -1204,7 +1204,7 @@
"go/descriptor;descriptor\370\001\001\242\002\003GPB\252\002\032Goog"
"le.Protobuf.Reflection"
;
-::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fdescriptor_2eproto = {
+static ::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fdescriptor_2eproto = {
false, InitDefaults_google_2fprotobuf_2fdescriptor_2eproto,
descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto,
"google/protobuf/descriptor.proto", &assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto, 6022,
@@ -1251,29 +1251,29 @@
}
}
-#if !defined(_MSC_VER) || _MSC_VER >= 1900
-const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_DOUBLE;
-const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FLOAT;
-const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT64;
-const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT64;
-const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT32;
-const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED64;
-const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED32;
-const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BOOL;
-const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_STRING;
-const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_GROUP;
-const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_MESSAGE;
-const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BYTES;
-const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT32;
-const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_ENUM;
-const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED32;
-const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED64;
-const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT32;
-const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT64;
-const FieldDescriptorProto_Type FieldDescriptorProto::Type_MIN;
-const FieldDescriptorProto_Type FieldDescriptorProto::Type_MAX;
-const int FieldDescriptorProto::Type_ARRAYSIZE;
-#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
+#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_DOUBLE;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FLOAT;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT64;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT64;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT32;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED64;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED32;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BOOL;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_STRING;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_GROUP;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_MESSAGE;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BYTES;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT32;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_ENUM;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED32;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED64;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT32;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT64;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::Type_MIN;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::Type_MAX;
+constexpr int FieldDescriptorProto::Type_ARRAYSIZE;
+#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor() {
::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[1];
@@ -1289,14 +1289,14 @@
}
}
-#if !defined(_MSC_VER) || _MSC_VER >= 1900
-const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_OPTIONAL;
-const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REQUIRED;
-const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REPEATED;
-const FieldDescriptorProto_Label FieldDescriptorProto::Label_MIN;
-const FieldDescriptorProto_Label FieldDescriptorProto::Label_MAX;
-const int FieldDescriptorProto::Label_ARRAYSIZE;
-#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
+#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
+constexpr FieldDescriptorProto_Label FieldDescriptorProto::LABEL_OPTIONAL;
+constexpr FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REQUIRED;
+constexpr FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REPEATED;
+constexpr FieldDescriptorProto_Label FieldDescriptorProto::Label_MIN;
+constexpr FieldDescriptorProto_Label FieldDescriptorProto::Label_MAX;
+constexpr int FieldDescriptorProto::Label_ARRAYSIZE;
+#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor() {
::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[2];
@@ -1312,14 +1312,14 @@
}
}
-#if !defined(_MSC_VER) || _MSC_VER >= 1900
-const FileOptions_OptimizeMode FileOptions::SPEED;
-const FileOptions_OptimizeMode FileOptions::CODE_SIZE;
-const FileOptions_OptimizeMode FileOptions::LITE_RUNTIME;
-const FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN;
-const FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX;
-const int FileOptions::OptimizeMode_ARRAYSIZE;
-#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
+#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
+constexpr FileOptions_OptimizeMode FileOptions::SPEED;
+constexpr FileOptions_OptimizeMode FileOptions::CODE_SIZE;
+constexpr FileOptions_OptimizeMode FileOptions::LITE_RUNTIME;
+constexpr FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN;
+constexpr FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX;
+constexpr int FileOptions::OptimizeMode_ARRAYSIZE;
+#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor() {
::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[3];
@@ -1335,14 +1335,14 @@
}
}
-#if !defined(_MSC_VER) || _MSC_VER >= 1900
-const FieldOptions_CType FieldOptions::STRING;
-const FieldOptions_CType FieldOptions::CORD;
-const FieldOptions_CType FieldOptions::STRING_PIECE;
-const FieldOptions_CType FieldOptions::CType_MIN;
-const FieldOptions_CType FieldOptions::CType_MAX;
-const int FieldOptions::CType_ARRAYSIZE;
-#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
+#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
+constexpr FieldOptions_CType FieldOptions::STRING;
+constexpr FieldOptions_CType FieldOptions::CORD;
+constexpr FieldOptions_CType FieldOptions::STRING_PIECE;
+constexpr FieldOptions_CType FieldOptions::CType_MIN;
+constexpr FieldOptions_CType FieldOptions::CType_MAX;
+constexpr int FieldOptions::CType_ARRAYSIZE;
+#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
const ::google::protobuf::EnumDescriptor* FieldOptions_JSType_descriptor() {
::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[4];
@@ -1358,14 +1358,14 @@
}
}
-#if !defined(_MSC_VER) || _MSC_VER >= 1900
-const FieldOptions_JSType FieldOptions::JS_NORMAL;
-const FieldOptions_JSType FieldOptions::JS_STRING;
-const FieldOptions_JSType FieldOptions::JS_NUMBER;
-const FieldOptions_JSType FieldOptions::JSType_MIN;
-const FieldOptions_JSType FieldOptions::JSType_MAX;
-const int FieldOptions::JSType_ARRAYSIZE;
-#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
+#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
+constexpr FieldOptions_JSType FieldOptions::JS_NORMAL;
+constexpr FieldOptions_JSType FieldOptions::JS_STRING;
+constexpr FieldOptions_JSType FieldOptions::JS_NUMBER;
+constexpr FieldOptions_JSType FieldOptions::JSType_MIN;
+constexpr FieldOptions_JSType FieldOptions::JSType_MAX;
+constexpr int FieldOptions::JSType_ARRAYSIZE;
+#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
const ::google::protobuf::EnumDescriptor* MethodOptions_IdempotencyLevel_descriptor() {
::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[5];
@@ -1381,14 +1381,14 @@
}
}
-#if !defined(_MSC_VER) || _MSC_VER >= 1900
-const MethodOptions_IdempotencyLevel MethodOptions::IDEMPOTENCY_UNKNOWN;
-const MethodOptions_IdempotencyLevel MethodOptions::NO_SIDE_EFFECTS;
-const MethodOptions_IdempotencyLevel MethodOptions::IDEMPOTENT;
-const MethodOptions_IdempotencyLevel MethodOptions::IdempotencyLevel_MIN;
-const MethodOptions_IdempotencyLevel MethodOptions::IdempotencyLevel_MAX;
-const int MethodOptions::IdempotencyLevel_ARRAYSIZE;
-#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
+#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
+constexpr MethodOptions_IdempotencyLevel MethodOptions::IDEMPOTENCY_UNKNOWN;
+constexpr MethodOptions_IdempotencyLevel MethodOptions::NO_SIDE_EFFECTS;
+constexpr MethodOptions_IdempotencyLevel MethodOptions::IDEMPOTENT;
+constexpr MethodOptions_IdempotencyLevel MethodOptions::IdempotencyLevel_MIN;
+constexpr MethodOptions_IdempotencyLevel MethodOptions::IdempotencyLevel_MAX;
+constexpr int MethodOptions::IdempotencyLevel_ARRAYSIZE;
+#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
// ===================================================================
@@ -1465,52 +1465,36 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* FileDescriptorSet::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<FileDescriptorSet*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* FileDescriptorSet::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// repeated .google.protobuf.FileDescriptorProto file = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_file(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::FileDescriptorProto::_InternalParse;
- object = msg->add_file();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool FileDescriptorSet::MergePartialFromCodedStream(
@@ -1919,237 +1903,139 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* FileDescriptorProto::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<FileDescriptorProto*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* FileDescriptorProto::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional string name = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_name(), ptr, ctx, "google.protobuf.FileDescriptorProto.name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FileDescriptorProto.name");
- object = msg->mutable_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional string package = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_package(), ptr, ctx, "google.protobuf.FileDescriptorProto.package");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FileDescriptorProto.package");
- object = msg->mutable_package();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// repeated string dependency = 3;
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(add_dependency(), ptr, ctx, "google.protobuf.FileDescriptorProto.dependency");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FileDescriptorProto.dependency");
- object = msg->add_dependency();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
break;
}
// repeated .google.protobuf.DescriptorProto message_type = 4;
case 4: {
if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_message_type(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::DescriptorProto::_InternalParse;
- object = msg->add_message_type();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 34 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 34 && (ptr += 1));
break;
}
// repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
case 5: {
if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_enum_type(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::EnumDescriptorProto::_InternalParse;
- object = msg->add_enum_type();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 42 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 42 && (ptr += 1));
break;
}
// repeated .google.protobuf.ServiceDescriptorProto service = 6;
case 6: {
if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_service(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::ServiceDescriptorProto::_InternalParse;
- object = msg->add_service();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 50 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 50 && (ptr += 1));
break;
}
// repeated .google.protobuf.FieldDescriptorProto extension = 7;
case 7: {
if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_extension(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::FieldDescriptorProto::_InternalParse;
- object = msg->add_extension();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 58 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 58 && (ptr += 1));
break;
}
// optional .google.protobuf.FileOptions options = 8;
case 8: {
if (static_cast<::google::protobuf::uint8>(tag) != 66) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(mutable_options(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::FileOptions::_InternalParse;
- object = msg->mutable_options();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
break;
}
// optional .google.protobuf.SourceCodeInfo source_code_info = 9;
case 9: {
if (static_cast<::google::protobuf::uint8>(tag) != 74) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(mutable_source_code_info(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::SourceCodeInfo::_InternalParse;
- object = msg->mutable_source_code_info();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
break;
}
// repeated int32 public_dependency = 10;
case 10: {
if (static_cast<::google::protobuf::uint8>(tag) == 80) {
do {
- msg->add_public_dependency(::google::protobuf::internal::ReadVarint(&ptr));
+ add_public_dependency(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 80 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 80 && (ptr += 1));
break;
} else if (static_cast<::google::protobuf::uint8>(tag) != 82) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::PackedInt32Parser(mutable_public_dependency(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::internal::PackedInt32Parser;
- object = msg->mutable_public_dependency();
- if (size > end - ptr) goto len_delim_till_end;
- auto newend = ptr + size;
- if (size) ptr = parser_till_end(ptr, newend, object, ctx);
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr == newend);
break;
}
// repeated int32 weak_dependency = 11;
case 11: {
if (static_cast<::google::protobuf::uint8>(tag) == 88) {
do {
- msg->add_weak_dependency(::google::protobuf::internal::ReadVarint(&ptr));
+ add_weak_dependency(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 88 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 88 && (ptr += 1));
break;
} else if (static_cast<::google::protobuf::uint8>(tag) != 90) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::PackedInt32Parser(mutable_weak_dependency(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::internal::PackedInt32Parser;
- object = msg->mutable_weak_dependency();
- if (size > end - ptr) goto len_delim_till_end;
- auto newend = ptr + size;
- if (size) ptr = parser_till_end(ptr, newend, object, ctx);
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr == newend);
break;
}
// optional string syntax = 12;
case 12: {
if (static_cast<::google::protobuf::uint8>(tag) != 98) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_syntax(), ptr, ctx, "google.protobuf.FileDescriptorProto.syntax");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FileDescriptorProto.syntax");
- object = msg->mutable_syntax();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool FileDescriptorProto::MergePartialFromCodedStream(
@@ -2939,63 +2825,47 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* DescriptorProto_ExtensionRange::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<DescriptorProto_ExtensionRange*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* DescriptorProto_ExtensionRange::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional int32 start = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
- msg->set_start(::google::protobuf::internal::ReadVarint(&ptr));
+ set_start(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional int32 end = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
- msg->set_end(::google::protobuf::internal::ReadVarint(&ptr));
+ set_end(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional .google.protobuf.ExtensionRangeOptions options = 3;
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(mutable_options(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::ExtensionRangeOptions::_InternalParse;
- object = msg->mutable_options();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream(
@@ -3351,43 +3221,36 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* DescriptorProto_ReservedRange::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<DescriptorProto_ReservedRange*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* DescriptorProto_ReservedRange::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional int32 start = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
- msg->set_start(::google::protobuf::internal::ReadVarint(&ptr));
+ set_start(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional int32 end = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
- msg->set_end(::google::protobuf::internal::ReadVarint(&ptr));
+ set_end(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
@@ -3775,200 +3638,120 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* DescriptorProto::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<DescriptorProto*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* DescriptorProto::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional string name = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_name(), ptr, ctx, "google.protobuf.DescriptorProto.name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.DescriptorProto.name");
- object = msg->mutable_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// repeated .google.protobuf.FieldDescriptorProto field = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_field(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::FieldDescriptorProto::_InternalParse;
- object = msg->add_field();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
break;
}
// repeated .google.protobuf.DescriptorProto nested_type = 3;
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_nested_type(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::DescriptorProto::_InternalParse;
- object = msg->add_nested_type();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
break;
}
// repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
case 4: {
if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_enum_type(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::EnumDescriptorProto::_InternalParse;
- object = msg->add_enum_type();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 34 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 34 && (ptr += 1));
break;
}
// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
case 5: {
if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_extension_range(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::DescriptorProto_ExtensionRange::_InternalParse;
- object = msg->add_extension_range();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 42 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 42 && (ptr += 1));
break;
}
// repeated .google.protobuf.FieldDescriptorProto extension = 6;
case 6: {
if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_extension(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::FieldDescriptorProto::_InternalParse;
- object = msg->add_extension();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 50 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 50 && (ptr += 1));
break;
}
// optional .google.protobuf.MessageOptions options = 7;
case 7: {
if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(mutable_options(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::MessageOptions::_InternalParse;
- object = msg->mutable_options();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
break;
}
// repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
case 8: {
if (static_cast<::google::protobuf::uint8>(tag) != 66) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_oneof_decl(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::OneofDescriptorProto::_InternalParse;
- object = msg->add_oneof_decl();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 66 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 66 && (ptr += 1));
break;
}
// repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
case 9: {
if (static_cast<::google::protobuf::uint8>(tag) != 74) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_reserved_range(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::DescriptorProto_ReservedRange::_InternalParse;
- object = msg->add_reserved_range();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 74 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 74 && (ptr += 1));
break;
}
// repeated string reserved_name = 10;
case 10: {
if (static_cast<::google::protobuf::uint8>(tag) != 82) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(add_reserved_name(), ptr, ctx, "google.protobuf.DescriptorProto.reserved_name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.DescriptorProto.reserved_name");
- object = msg->add_reserved_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 82 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 82 && (ptr += 1));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool DescriptorProto::MergePartialFromCodedStream(
@@ -4631,60 +4414,42 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* ExtensionRangeOptions::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<ExtensionRangeOptions*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* ExtensionRangeOptions::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
case 999: {
if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_uninterpreted_option(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::UninterpretedOption::_InternalParse;
- object = msg->add_uninterpreted_option();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 16058 && (ptr += 2));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 16058 && (ptr += 2));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
if ((8000u <= tag)) {
- auto res = msg->_extensions_.ParseField(tag, {_InternalParse, msg}, ptr, end,
- internal_default_instance(), &msg->_internal_metadata_, ctx);
- ptr = res.first;
+ ptr = _extensions_.ParseField(tag, ptr,
+ internal_default_instance(), &_internal_metadata_, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
- continue;
+ break;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool ExtensionRangeOptions::MergePartialFromCodedStream(
@@ -5110,54 +4875,30 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* FieldDescriptorProto::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<FieldDescriptorProto*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* FieldDescriptorProto::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional string name = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_name(), ptr, ctx, "google.protobuf.FieldDescriptorProto.name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FieldDescriptorProto.name");
- object = msg->mutable_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional string extendee = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_extendee(), ptr, ctx, "google.protobuf.FieldDescriptorProto.extendee");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FieldDescriptorProto.extendee");
- object = msg->mutable_extendee();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional int32 number = 3;
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
- msg->set_number(::google::protobuf::internal::ReadVarint(&ptr));
+ set_number(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
@@ -5165,116 +4906,75 @@
case 4: {
if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
if (!::google::protobuf::FieldDescriptorProto_Label_IsValid(val)) {
- ::google::protobuf::internal::WriteVarint(4, val, msg->mutable_unknown_fields());
+ ::google::protobuf::internal::WriteVarint(4, val, mutable_unknown_fields());
break;
}
- msg->set_label(static_cast<::google::protobuf::FieldDescriptorProto_Label>(val));
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ set_label(static_cast<::google::protobuf::FieldDescriptorProto_Label>(val));
break;
}
// optional .google.protobuf.FieldDescriptorProto.Type type = 5;
case 5: {
if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
if (!::google::protobuf::FieldDescriptorProto_Type_IsValid(val)) {
- ::google::protobuf::internal::WriteVarint(5, val, msg->mutable_unknown_fields());
+ ::google::protobuf::internal::WriteVarint(5, val, mutable_unknown_fields());
break;
}
- msg->set_type(static_cast<::google::protobuf::FieldDescriptorProto_Type>(val));
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ set_type(static_cast<::google::protobuf::FieldDescriptorProto_Type>(val));
break;
}
// optional string type_name = 6;
case 6: {
if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_type_name(), ptr, ctx, "google.protobuf.FieldDescriptorProto.type_name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FieldDescriptorProto.type_name");
- object = msg->mutable_type_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional string default_value = 7;
case 7: {
if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_default_value(), ptr, ctx, "google.protobuf.FieldDescriptorProto.default_value");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FieldDescriptorProto.default_value");
- object = msg->mutable_default_value();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional .google.protobuf.FieldOptions options = 8;
case 8: {
if (static_cast<::google::protobuf::uint8>(tag) != 66) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(mutable_options(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::FieldOptions::_InternalParse;
- object = msg->mutable_options();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
break;
}
// optional int32 oneof_index = 9;
case 9: {
if (static_cast<::google::protobuf::uint8>(tag) != 72) goto handle_unusual;
- msg->set_oneof_index(::google::protobuf::internal::ReadVarint(&ptr));
+ set_oneof_index(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional string json_name = 10;
case 10: {
if (static_cast<::google::protobuf::uint8>(tag) != 82) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_json_name(), ptr, ctx, "google.protobuf.FieldDescriptorProto.json_name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FieldDescriptorProto.json_name");
- object = msg->mutable_json_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool FieldDescriptorProto::MergePartialFromCodedStream(
@@ -5991,69 +5691,40 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* OneofDescriptorProto::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<OneofDescriptorProto*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* OneofDescriptorProto::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional string name = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_name(), ptr, ctx, "google.protobuf.OneofDescriptorProto.name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.OneofDescriptorProto.name");
- object = msg->mutable_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional .google.protobuf.OneofOptions options = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(mutable_options(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::OneofOptions::_InternalParse;
- object = msg->mutable_options();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool OneofDescriptorProto::MergePartialFromCodedStream(
@@ -6388,43 +6059,36 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* EnumDescriptorProto_EnumReservedRange::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<EnumDescriptorProto_EnumReservedRange*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* EnumDescriptorProto_EnumReservedRange::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional int32 start = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
- msg->set_start(::google::protobuf::internal::ReadVarint(&ptr));
+ set_start(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional int32 end = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
- msg->set_end(::google::protobuf::internal::ReadVarint(&ptr));
+ set_end(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
@@ -6792,120 +6456,70 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* EnumDescriptorProto::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<EnumDescriptorProto*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* EnumDescriptorProto::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional string name = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_name(), ptr, ctx, "google.protobuf.EnumDescriptorProto.name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.EnumDescriptorProto.name");
- object = msg->mutable_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// repeated .google.protobuf.EnumValueDescriptorProto value = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_value(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::EnumValueDescriptorProto::_InternalParse;
- object = msg->add_value();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
break;
}
// optional .google.protobuf.EnumOptions options = 3;
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(mutable_options(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::EnumOptions::_InternalParse;
- object = msg->mutable_options();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
break;
}
// repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
case 4: {
if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_reserved_range(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::EnumDescriptorProto_EnumReservedRange::_InternalParse;
- object = msg->add_reserved_range();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 34 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 34 && (ptr += 1));
break;
}
// repeated string reserved_name = 5;
case 5: {
if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(add_reserved_name(), ptr, ctx, "google.protobuf.EnumDescriptorProto.reserved_name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.EnumDescriptorProto.reserved_name");
- object = msg->add_reserved_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 42 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 42 && (ptr += 1));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool EnumDescriptorProto::MergePartialFromCodedStream(
@@ -7411,76 +7025,47 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* EnumValueDescriptorProto::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<EnumValueDescriptorProto*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* EnumValueDescriptorProto::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional string name = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_name(), ptr, ctx, "google.protobuf.EnumValueDescriptorProto.name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.EnumValueDescriptorProto.name");
- object = msg->mutable_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional int32 number = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
- msg->set_number(::google::protobuf::internal::ReadVarint(&ptr));
+ set_number(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional .google.protobuf.EnumValueOptions options = 3;
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(mutable_options(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::EnumValueOptions::_InternalParse;
- object = msg->mutable_options();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool EnumValueDescriptorProto::MergePartialFromCodedStream(
@@ -7888,85 +7473,50 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* ServiceDescriptorProto::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<ServiceDescriptorProto*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* ServiceDescriptorProto::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional string name = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_name(), ptr, ctx, "google.protobuf.ServiceDescriptorProto.name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.ServiceDescriptorProto.name");
- object = msg->mutable_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// repeated .google.protobuf.MethodDescriptorProto method = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_method(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::MethodDescriptorProto::_InternalParse;
- object = msg->add_method();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
break;
}
// optional .google.protobuf.ServiceOptions options = 3;
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(mutable_options(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::ServiceOptions::_InternalParse;
- object = msg->mutable_options();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool ServiceDescriptorProto::MergePartialFromCodedStream(
@@ -8421,115 +7971,68 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* MethodDescriptorProto::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<MethodDescriptorProto*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* MethodDescriptorProto::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional string name = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_name(), ptr, ctx, "google.protobuf.MethodDescriptorProto.name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.MethodDescriptorProto.name");
- object = msg->mutable_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional string input_type = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_input_type(), ptr, ctx, "google.protobuf.MethodDescriptorProto.input_type");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.MethodDescriptorProto.input_type");
- object = msg->mutable_input_type();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional string output_type = 3;
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_output_type(), ptr, ctx, "google.protobuf.MethodDescriptorProto.output_type");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.MethodDescriptorProto.output_type");
- object = msg->mutable_output_type();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional .google.protobuf.MethodOptions options = 4;
case 4: {
if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(mutable_options(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::MethodOptions::_InternalParse;
- object = msg->mutable_options();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
break;
}
// optional bool client_streaming = 5 [default = false];
case 5: {
if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
- msg->set_client_streaming(::google::protobuf::internal::ReadVarint(&ptr));
+ set_client_streaming(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional bool server_streaming = 6 [default = false];
case 6: {
if (static_cast<::google::protobuf::uint8>(tag) != 48) goto handle_unusual;
- msg->set_server_streaming(::google::protobuf::internal::ReadVarint(&ptr));
+ set_server_streaming(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool MethodDescriptorProto::MergePartialFromCodedStream(
@@ -9217,299 +8720,187 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* FileOptions::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<FileOptions*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* FileOptions::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional string java_package = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_java_package(), ptr, ctx, "google.protobuf.FileOptions.java_package");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.java_package");
- object = msg->mutable_java_package();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional string java_outer_classname = 8;
case 8: {
if (static_cast<::google::protobuf::uint8>(tag) != 66) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_java_outer_classname(), ptr, ctx, "google.protobuf.FileOptions.java_outer_classname");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.java_outer_classname");
- object = msg->mutable_java_outer_classname();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
case 9: {
if (static_cast<::google::protobuf::uint8>(tag) != 72) goto handle_unusual;
::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
if (!::google::protobuf::FileOptions_OptimizeMode_IsValid(val)) {
- ::google::protobuf::internal::WriteVarint(9, val, msg->mutable_unknown_fields());
+ ::google::protobuf::internal::WriteVarint(9, val, mutable_unknown_fields());
break;
}
- msg->set_optimize_for(static_cast<::google::protobuf::FileOptions_OptimizeMode>(val));
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ set_optimize_for(static_cast<::google::protobuf::FileOptions_OptimizeMode>(val));
break;
}
// optional bool java_multiple_files = 10 [default = false];
case 10: {
if (static_cast<::google::protobuf::uint8>(tag) != 80) goto handle_unusual;
- msg->set_java_multiple_files(::google::protobuf::internal::ReadVarint(&ptr));
+ set_java_multiple_files(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional string go_package = 11;
case 11: {
if (static_cast<::google::protobuf::uint8>(tag) != 90) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_go_package(), ptr, ctx, "google.protobuf.FileOptions.go_package");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.go_package");
- object = msg->mutable_go_package();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional bool cc_generic_services = 16 [default = false];
case 16: {
if (static_cast<::google::protobuf::uint8>(tag) != 128) goto handle_unusual;
- msg->set_cc_generic_services(::google::protobuf::internal::ReadVarint(&ptr));
+ set_cc_generic_services(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional bool java_generic_services = 17 [default = false];
case 17: {
if (static_cast<::google::protobuf::uint8>(tag) != 136) goto handle_unusual;
- msg->set_java_generic_services(::google::protobuf::internal::ReadVarint(&ptr));
+ set_java_generic_services(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional bool py_generic_services = 18 [default = false];
case 18: {
if (static_cast<::google::protobuf::uint8>(tag) != 144) goto handle_unusual;
- msg->set_py_generic_services(::google::protobuf::internal::ReadVarint(&ptr));
+ set_py_generic_services(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional bool java_generate_equals_and_hash = 20 [deprecated = true];
case 20: {
if (static_cast<::google::protobuf::uint8>(tag) != 160) goto handle_unusual;
- msg->set_java_generate_equals_and_hash(::google::protobuf::internal::ReadVarint(&ptr));
+ set_java_generate_equals_and_hash(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional bool deprecated = 23 [default = false];
case 23: {
if (static_cast<::google::protobuf::uint8>(tag) != 184) goto handle_unusual;
- msg->set_deprecated(::google::protobuf::internal::ReadVarint(&ptr));
+ set_deprecated(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional bool java_string_check_utf8 = 27 [default = false];
case 27: {
if (static_cast<::google::protobuf::uint8>(tag) != 216) goto handle_unusual;
- msg->set_java_string_check_utf8(::google::protobuf::internal::ReadVarint(&ptr));
+ set_java_string_check_utf8(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional bool cc_enable_arenas = 31 [default = false];
case 31: {
if (static_cast<::google::protobuf::uint8>(tag) != 248) goto handle_unusual;
- msg->set_cc_enable_arenas(::google::protobuf::internal::ReadVarint(&ptr));
+ set_cc_enable_arenas(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional string objc_class_prefix = 36;
case 36: {
if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_objc_class_prefix(), ptr, ctx, "google.protobuf.FileOptions.objc_class_prefix");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.objc_class_prefix");
- object = msg->mutable_objc_class_prefix();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional string csharp_namespace = 37;
case 37: {
if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_csharp_namespace(), ptr, ctx, "google.protobuf.FileOptions.csharp_namespace");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.csharp_namespace");
- object = msg->mutable_csharp_namespace();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional string swift_prefix = 39;
case 39: {
if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_swift_prefix(), ptr, ctx, "google.protobuf.FileOptions.swift_prefix");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.swift_prefix");
- object = msg->mutable_swift_prefix();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional string php_class_prefix = 40;
case 40: {
if (static_cast<::google::protobuf::uint8>(tag) != 66) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_php_class_prefix(), ptr, ctx, "google.protobuf.FileOptions.php_class_prefix");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.php_class_prefix");
- object = msg->mutable_php_class_prefix();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional string php_namespace = 41;
case 41: {
if (static_cast<::google::protobuf::uint8>(tag) != 74) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_php_namespace(), ptr, ctx, "google.protobuf.FileOptions.php_namespace");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.php_namespace");
- object = msg->mutable_php_namespace();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional bool php_generic_services = 42 [default = false];
case 42: {
if (static_cast<::google::protobuf::uint8>(tag) != 80) goto handle_unusual;
- msg->set_php_generic_services(::google::protobuf::internal::ReadVarint(&ptr));
+ set_php_generic_services(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional string php_metadata_namespace = 44;
case 44: {
if (static_cast<::google::protobuf::uint8>(tag) != 98) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_php_metadata_namespace(), ptr, ctx, "google.protobuf.FileOptions.php_metadata_namespace");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.php_metadata_namespace");
- object = msg->mutable_php_metadata_namespace();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional string ruby_package = 45;
case 45: {
if (static_cast<::google::protobuf::uint8>(tag) != 106) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_ruby_package(), ptr, ctx, "google.protobuf.FileOptions.ruby_package");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.ruby_package");
- object = msg->mutable_ruby_package();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
case 999: {
if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_uninterpreted_option(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::UninterpretedOption::_InternalParse;
- object = msg->add_uninterpreted_option();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 16058 && (ptr += 2));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 16058 && (ptr += 2));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
if ((8000u <= tag)) {
- auto res = msg->_extensions_.ParseField(tag, {_InternalParse, msg}, ptr, end,
- internal_default_instance(), &msg->_internal_metadata_, ctx);
- ptr = res.first;
+ ptr = _extensions_.ParseField(tag, ptr,
+ internal_default_instance(), &_internal_metadata_, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
- continue;
+ break;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool FileOptions::MergePartialFromCodedStream(
@@ -10654,43 +10045,37 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* MessageOptions::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<MessageOptions*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* MessageOptions::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional bool message_set_wire_format = 1 [default = false];
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
- msg->set_message_set_wire_format(::google::protobuf::internal::ReadVarint(&ptr));
+ set_message_set_wire_format(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional bool no_standard_descriptor_accessor = 2 [default = false];
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
- msg->set_no_standard_descriptor_accessor(::google::protobuf::internal::ReadVarint(&ptr));
+ set_no_standard_descriptor_accessor(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional bool deprecated = 3 [default = false];
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
- msg->set_deprecated(::google::protobuf::internal::ReadVarint(&ptr));
+ set_deprecated(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional bool map_entry = 7;
case 7: {
if (static_cast<::google::protobuf::uint8>(tag) != 56) goto handle_unusual;
- msg->set_map_entry(::google::protobuf::internal::ReadVarint(&ptr));
+ set_map_entry(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
@@ -10698,44 +10083,32 @@
case 999: {
if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_uninterpreted_option(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::UninterpretedOption::_InternalParse;
- object = msg->add_uninterpreted_option();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 16058 && (ptr += 2));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 16058 && (ptr += 2));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
if ((8000u <= tag)) {
- auto res = msg->_extensions_.ParseField(tag, {_InternalParse, msg}, ptr, end,
- internal_default_instance(), &msg->_internal_metadata_, ctx);
- ptr = res.first;
+ ptr = _extensions_.ParseField(tag, ptr,
+ internal_default_instance(), &_internal_metadata_, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
- continue;
+ break;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool MessageOptions::MergePartialFromCodedStream(
@@ -11201,48 +10574,42 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* FieldOptions::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<FieldOptions*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* FieldOptions::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
if (!::google::protobuf::FieldOptions_CType_IsValid(val)) {
- ::google::protobuf::internal::WriteVarint(1, val, msg->mutable_unknown_fields());
+ ::google::protobuf::internal::WriteVarint(1, val, mutable_unknown_fields());
break;
}
- msg->set_ctype(static_cast<::google::protobuf::FieldOptions_CType>(val));
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ set_ctype(static_cast<::google::protobuf::FieldOptions_CType>(val));
break;
}
// optional bool packed = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
- msg->set_packed(::google::protobuf::internal::ReadVarint(&ptr));
+ set_packed(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional bool deprecated = 3 [default = false];
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
- msg->set_deprecated(::google::protobuf::internal::ReadVarint(&ptr));
+ set_deprecated(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional bool lazy = 5 [default = false];
case 5: {
if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
- msg->set_lazy(::google::protobuf::internal::ReadVarint(&ptr));
+ set_lazy(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
@@ -11250,18 +10617,18 @@
case 6: {
if (static_cast<::google::protobuf::uint8>(tag) != 48) goto handle_unusual;
::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
if (!::google::protobuf::FieldOptions_JSType_IsValid(val)) {
- ::google::protobuf::internal::WriteVarint(6, val, msg->mutable_unknown_fields());
+ ::google::protobuf::internal::WriteVarint(6, val, mutable_unknown_fields());
break;
}
- msg->set_jstype(static_cast<::google::protobuf::FieldOptions_JSType>(val));
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ set_jstype(static_cast<::google::protobuf::FieldOptions_JSType>(val));
break;
}
// optional bool weak = 10 [default = false];
case 10: {
if (static_cast<::google::protobuf::uint8>(tag) != 80) goto handle_unusual;
- msg->set_weak(::google::protobuf::internal::ReadVarint(&ptr));
+ set_weak(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
@@ -11269,44 +10636,32 @@
case 999: {
if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_uninterpreted_option(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::UninterpretedOption::_InternalParse;
- object = msg->add_uninterpreted_option();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 16058 && (ptr += 2));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 16058 && (ptr += 2));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
if ((8000u <= tag)) {
- auto res = msg->_extensions_.ParseField(tag, {_InternalParse, msg}, ptr, end,
- internal_default_instance(), &msg->_internal_metadata_, ctx);
- ptr = res.first;
+ ptr = _extensions_.ParseField(tag, ptr,
+ internal_default_instance(), &_internal_metadata_, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
- continue;
+ break;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool FieldOptions::MergePartialFromCodedStream(
@@ -11818,60 +11173,42 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* OneofOptions::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<OneofOptions*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* OneofOptions::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
case 999: {
if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_uninterpreted_option(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::UninterpretedOption::_InternalParse;
- object = msg->add_uninterpreted_option();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 16058 && (ptr += 2));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 16058 && (ptr += 2));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
if ((8000u <= tag)) {
- auto res = msg->_extensions_.ParseField(tag, {_InternalParse, msg}, ptr, end,
- internal_default_instance(), &msg->_internal_metadata_, ctx);
- ptr = res.first;
+ ptr = _extensions_.ParseField(tag, ptr,
+ internal_default_instance(), &_internal_metadata_, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
- continue;
+ break;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool OneofOptions::MergePartialFromCodedStream(
@@ -12181,29 +11518,23 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* EnumOptions::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<EnumOptions*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* EnumOptions::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional bool allow_alias = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
- msg->set_allow_alias(::google::protobuf::internal::ReadVarint(&ptr));
+ set_allow_alias(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional bool deprecated = 3 [default = false];
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
- msg->set_deprecated(::google::protobuf::internal::ReadVarint(&ptr));
+ set_deprecated(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
@@ -12211,44 +11542,32 @@
case 999: {
if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_uninterpreted_option(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::UninterpretedOption::_InternalParse;
- object = msg->add_uninterpreted_option();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 16058 && (ptr += 2));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 16058 && (ptr += 2));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
if ((8000u <= tag)) {
- auto res = msg->_extensions_.ParseField(tag, {_InternalParse, msg}, ptr, end,
- internal_default_instance(), &msg->_internal_metadata_, ctx);
- ptr = res.first;
+ ptr = _extensions_.ParseField(tag, ptr,
+ internal_default_instance(), &_internal_metadata_, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
- continue;
+ break;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool EnumOptions::MergePartialFromCodedStream(
@@ -12621,22 +11940,16 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* EnumValueOptions::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<EnumValueOptions*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* EnumValueOptions::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional bool deprecated = 1 [default = false];
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
- msg->set_deprecated(::google::protobuf::internal::ReadVarint(&ptr));
+ set_deprecated(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
@@ -12644,44 +11957,32 @@
case 999: {
if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_uninterpreted_option(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::UninterpretedOption::_InternalParse;
- object = msg->add_uninterpreted_option();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 16058 && (ptr += 2));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 16058 && (ptr += 2));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
if ((8000u <= tag)) {
- auto res = msg->_extensions_.ParseField(tag, {_InternalParse, msg}, ptr, end,
- internal_default_instance(), &msg->_internal_metadata_, ctx);
- ptr = res.first;
+ ptr = _extensions_.ParseField(tag, ptr,
+ internal_default_instance(), &_internal_metadata_, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
- continue;
+ break;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool EnumValueOptions::MergePartialFromCodedStream(
@@ -13016,22 +12317,16 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* ServiceOptions::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<ServiceOptions*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* ServiceOptions::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional bool deprecated = 33 [default = false];
case 33: {
if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
- msg->set_deprecated(::google::protobuf::internal::ReadVarint(&ptr));
+ set_deprecated(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
@@ -13039,44 +12334,32 @@
case 999: {
if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_uninterpreted_option(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::UninterpretedOption::_InternalParse;
- object = msg->add_uninterpreted_option();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 16058 && (ptr += 2));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 16058 && (ptr += 2));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
if ((8000u <= tag)) {
- auto res = msg->_extensions_.ParseField(tag, {_InternalParse, msg}, ptr, end,
- internal_default_instance(), &msg->_internal_metadata_, ctx);
- ptr = res.first;
+ ptr = _extensions_.ParseField(tag, ptr,
+ internal_default_instance(), &_internal_metadata_, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
- continue;
+ break;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool ServiceOptions::MergePartialFromCodedStream(
@@ -13424,22 +12707,16 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* MethodOptions::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<MethodOptions*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* MethodOptions::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// optional bool deprecated = 33 [default = false];
case 33: {
if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
- msg->set_deprecated(::google::protobuf::internal::ReadVarint(&ptr));
+ set_deprecated(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
@@ -13447,56 +12724,44 @@
case 34: {
if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
if (!::google::protobuf::MethodOptions_IdempotencyLevel_IsValid(val)) {
- ::google::protobuf::internal::WriteVarint(34, val, msg->mutable_unknown_fields());
+ ::google::protobuf::internal::WriteVarint(34, val, mutable_unknown_fields());
break;
}
- msg->set_idempotency_level(static_cast<::google::protobuf::MethodOptions_IdempotencyLevel>(val));
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ set_idempotency_level(static_cast<::google::protobuf::MethodOptions_IdempotencyLevel>(val));
break;
}
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
case 999: {
if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_uninterpreted_option(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::UninterpretedOption::_InternalParse;
- object = msg->add_uninterpreted_option();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 16058 && (ptr += 2));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 16058 && (ptr += 2));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
if ((8000u <= tag)) {
- auto res = msg->_extensions_.ParseField(tag, {_InternalParse, msg}, ptr, end,
- internal_default_instance(), &msg->_internal_metadata_, ctx);
- ptr = res.first;
+ ptr = _extensions_.ParseField(tag, ptr,
+ internal_default_instance(), &_internal_metadata_, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
- continue;
+ break;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool MethodOptions::MergePartialFromCodedStream(
@@ -13886,63 +13151,40 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* UninterpretedOption_NamePart::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<UninterpretedOption_NamePart*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* UninterpretedOption_NamePart::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// required string name_part = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_name_part(), ptr, ctx, "google.protobuf.UninterpretedOption.NamePart.name_part");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.UninterpretedOption.NamePart.name_part");
- object = msg->mutable_name_part();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// required bool is_extension = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
- msg->set_is_extension(::google::protobuf::internal::ReadVarint(&ptr));
+ set_is_extension(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool UninterpretedOption_NamePart::MergePartialFromCodedStream(
@@ -14342,124 +13584,78 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* UninterpretedOption::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<UninterpretedOption*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* UninterpretedOption::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_name(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::UninterpretedOption_NamePart::_InternalParse;
- object = msg->add_name();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
break;
}
// optional string identifier_value = 3;
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_identifier_value(), ptr, ctx, "google.protobuf.UninterpretedOption.identifier_value");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.UninterpretedOption.identifier_value");
- object = msg->mutable_identifier_value();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional uint64 positive_int_value = 4;
case 4: {
if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
- msg->set_positive_int_value(::google::protobuf::internal::ReadVarint(&ptr));
+ set_positive_int_value(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional int64 negative_int_value = 5;
case 5: {
if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
- msg->set_negative_int_value(::google::protobuf::internal::ReadVarint(&ptr));
+ set_negative_int_value(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional double double_value = 6;
case 6: {
if (static_cast<::google::protobuf::uint8>(tag) != 49) goto handle_unusual;
- msg->set_double_value(::google::protobuf::io::UnalignedLoad<double>(ptr));
+ set_double_value(::google::protobuf::internal::UnalignedLoad<double>(ptr));
ptr += sizeof(double);
break;
}
// optional bytes string_value = 7;
case 7: {
if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParser(mutable_string_value(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- object = msg->mutable_string_value();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParser;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheck(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional string aggregate_value = 8;
case 8: {
if (static_cast<::google::protobuf::uint8>(tag) != 66) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_aggregate_value(), ptr, ctx, "google.protobuf.UninterpretedOption.aggregate_value");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.UninterpretedOption.aggregate_value");
- object = msg->mutable_aggregate_value();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool UninterpretedOption::MergePartialFromCodedStream(
@@ -15008,131 +14204,78 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* SourceCodeInfo_Location::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<SourceCodeInfo_Location*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* SourceCodeInfo_Location::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// repeated int32 path = 1 [packed = true];
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) == 10) {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::PackedInt32Parser(mutable_path(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::internal::PackedInt32Parser;
- object = msg->mutable_path();
- if (size > end - ptr) goto len_delim_till_end;
- auto newend = ptr + size;
- if (size) ptr = parser_till_end(ptr, newend, object, ctx);
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr == newend);
break;
} else if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
do {
- msg->add_path(::google::protobuf::internal::ReadVarint(&ptr));
+ add_path(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 8 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 8 && (ptr += 1));
break;
}
// repeated int32 span = 2 [packed = true];
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) == 18) {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::PackedInt32Parser(mutable_span(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::internal::PackedInt32Parser;
- object = msg->mutable_span();
- if (size > end - ptr) goto len_delim_till_end;
- auto newend = ptr + size;
- if (size) ptr = parser_till_end(ptr, newend, object, ctx);
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr == newend);
break;
} else if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
do {
- msg->add_span(::google::protobuf::internal::ReadVarint(&ptr));
+ add_span(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 16 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 16 && (ptr += 1));
break;
}
// optional string leading_comments = 3;
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_leading_comments(), ptr, ctx, "google.protobuf.SourceCodeInfo.Location.leading_comments");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.SourceCodeInfo.Location.leading_comments");
- object = msg->mutable_leading_comments();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional string trailing_comments = 4;
case 4: {
if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_trailing_comments(), ptr, ctx, "google.protobuf.SourceCodeInfo.Location.trailing_comments");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.SourceCodeInfo.Location.trailing_comments");
- object = msg->mutable_trailing_comments();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// repeated string leading_detached_comments = 6;
case 6: {
if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(add_leading_detached_comments(), ptr, ctx, "google.protobuf.SourceCodeInfo.Location.leading_detached_comments");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.SourceCodeInfo.Location.leading_detached_comments");
- object = msg->add_leading_detached_comments();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 50 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 50 && (ptr += 1));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool SourceCodeInfo_Location::MergePartialFromCodedStream(
@@ -15623,52 +14766,36 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* SourceCodeInfo::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<SourceCodeInfo*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* SourceCodeInfo::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// repeated .google.protobuf.SourceCodeInfo.Location location = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_location(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::SourceCodeInfo_Location::_InternalParse;
- object = msg->add_location();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool SourceCodeInfo::MergePartialFromCodedStream(
@@ -15970,90 +15097,61 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* GeneratedCodeInfo_Annotation::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<GeneratedCodeInfo_Annotation*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* GeneratedCodeInfo_Annotation::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// repeated int32 path = 1 [packed = true];
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) == 10) {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::PackedInt32Parser(mutable_path(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::internal::PackedInt32Parser;
- object = msg->mutable_path();
- if (size > end - ptr) goto len_delim_till_end;
- auto newend = ptr + size;
- if (size) ptr = parser_till_end(ptr, newend, object, ctx);
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr == newend);
break;
} else if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
do {
- msg->add_path(::google::protobuf::internal::ReadVarint(&ptr));
+ add_path(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 8 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 8 && (ptr += 1));
break;
}
// optional string source_file = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8Verify(mutable_source_file(), ptr, ctx, "google.protobuf.GeneratedCodeInfo.Annotation.source_file");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.GeneratedCodeInfo.Annotation.source_file");
- object = msg->mutable_source_file();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// optional int32 begin = 3;
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
- msg->set_begin(::google::protobuf::internal::ReadVarint(&ptr));
+ set_begin(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// optional int32 end = 4;
case 4: {
if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
- msg->set_end(::google::protobuf::internal::ReadVarint(&ptr));
+ set_end(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool GeneratedCodeInfo_Annotation::MergePartialFromCodedStream(
@@ -16462,52 +15560,36 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* GeneratedCodeInfo::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<GeneratedCodeInfo*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* GeneratedCodeInfo::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_annotation(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::GeneratedCodeInfo_Annotation::_InternalParse;
- object = msg->add_annotation();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool GeneratedCodeInfo::MergePartialFromCodedStream(
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h
index 1860184..7df5d38 100644
--- a/src/google/protobuf/descriptor.pb.h
+++ b/src/google/protobuf/descriptor.pb.h
@@ -32,6 +32,13 @@
#include <google/protobuf/extension_set.h> // IWYU pragma: export
#include <google/protobuf/generated_enum_reflection.h>
#include <google/protobuf/unknown_field_set.h>
+namespace google {
+namespace protobuf {
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+} // namespace protobuf
+} // namespace google
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto PROTOBUF_EXPORT
@@ -185,9 +192,9 @@
FieldDescriptorProto_Type_TYPE_SINT64 = 18
};
PROTOBUF_EXPORT bool FieldDescriptorProto_Type_IsValid(int value);
-const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE;
-const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64;
-const int FieldDescriptorProto_Type_Type_ARRAYSIZE = FieldDescriptorProto_Type_Type_MAX + 1;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64;
+constexpr int FieldDescriptorProto_Type_Type_ARRAYSIZE = FieldDescriptorProto_Type_Type_MAX + 1;
PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor();
inline const ::std::string& FieldDescriptorProto_Type_Name(FieldDescriptorProto_Type value) {
@@ -205,9 +212,9 @@
FieldDescriptorProto_Label_LABEL_REPEATED = 3
};
PROTOBUF_EXPORT bool FieldDescriptorProto_Label_IsValid(int value);
-const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL;
-const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED;
-const int FieldDescriptorProto_Label_Label_ARRAYSIZE = FieldDescriptorProto_Label_Label_MAX + 1;
+constexpr FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL;
+constexpr FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED;
+constexpr int FieldDescriptorProto_Label_Label_ARRAYSIZE = FieldDescriptorProto_Label_Label_MAX + 1;
PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor();
inline const ::std::string& FieldDescriptorProto_Label_Name(FieldDescriptorProto_Label value) {
@@ -225,9 +232,9 @@
FileOptions_OptimizeMode_LITE_RUNTIME = 3
};
PROTOBUF_EXPORT bool FileOptions_OptimizeMode_IsValid(int value);
-const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MIN = FileOptions_OptimizeMode_SPEED;
-const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MAX = FileOptions_OptimizeMode_LITE_RUNTIME;
-const int FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE = FileOptions_OptimizeMode_OptimizeMode_MAX + 1;
+constexpr FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MIN = FileOptions_OptimizeMode_SPEED;
+constexpr FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MAX = FileOptions_OptimizeMode_LITE_RUNTIME;
+constexpr int FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE = FileOptions_OptimizeMode_OptimizeMode_MAX + 1;
PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor();
inline const ::std::string& FileOptions_OptimizeMode_Name(FileOptions_OptimizeMode value) {
@@ -245,9 +252,9 @@
FieldOptions_CType_STRING_PIECE = 2
};
PROTOBUF_EXPORT bool FieldOptions_CType_IsValid(int value);
-const FieldOptions_CType FieldOptions_CType_CType_MIN = FieldOptions_CType_STRING;
-const FieldOptions_CType FieldOptions_CType_CType_MAX = FieldOptions_CType_STRING_PIECE;
-const int FieldOptions_CType_CType_ARRAYSIZE = FieldOptions_CType_CType_MAX + 1;
+constexpr FieldOptions_CType FieldOptions_CType_CType_MIN = FieldOptions_CType_STRING;
+constexpr FieldOptions_CType FieldOptions_CType_CType_MAX = FieldOptions_CType_STRING_PIECE;
+constexpr int FieldOptions_CType_CType_ARRAYSIZE = FieldOptions_CType_CType_MAX + 1;
PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor();
inline const ::std::string& FieldOptions_CType_Name(FieldOptions_CType value) {
@@ -265,9 +272,9 @@
FieldOptions_JSType_JS_NUMBER = 2
};
PROTOBUF_EXPORT bool FieldOptions_JSType_IsValid(int value);
-const FieldOptions_JSType FieldOptions_JSType_JSType_MIN = FieldOptions_JSType_JS_NORMAL;
-const FieldOptions_JSType FieldOptions_JSType_JSType_MAX = FieldOptions_JSType_JS_NUMBER;
-const int FieldOptions_JSType_JSType_ARRAYSIZE = FieldOptions_JSType_JSType_MAX + 1;
+constexpr FieldOptions_JSType FieldOptions_JSType_JSType_MIN = FieldOptions_JSType_JS_NORMAL;
+constexpr FieldOptions_JSType FieldOptions_JSType_JSType_MAX = FieldOptions_JSType_JS_NUMBER;
+constexpr int FieldOptions_JSType_JSType_ARRAYSIZE = FieldOptions_JSType_JSType_MAX + 1;
PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldOptions_JSType_descriptor();
inline const ::std::string& FieldOptions_JSType_Name(FieldOptions_JSType value) {
@@ -285,9 +292,9 @@
MethodOptions_IdempotencyLevel_IDEMPOTENT = 2
};
PROTOBUF_EXPORT bool MethodOptions_IdempotencyLevel_IsValid(int value);
-const MethodOptions_IdempotencyLevel MethodOptions_IdempotencyLevel_IdempotencyLevel_MIN = MethodOptions_IdempotencyLevel_IDEMPOTENCY_UNKNOWN;
-const MethodOptions_IdempotencyLevel MethodOptions_IdempotencyLevel_IdempotencyLevel_MAX = MethodOptions_IdempotencyLevel_IDEMPOTENT;
-const int MethodOptions_IdempotencyLevel_IdempotencyLevel_ARRAYSIZE = MethodOptions_IdempotencyLevel_IdempotencyLevel_MAX + 1;
+constexpr MethodOptions_IdempotencyLevel MethodOptions_IdempotencyLevel_IdempotencyLevel_MIN = MethodOptions_IdempotencyLevel_IDEMPOTENCY_UNKNOWN;
+constexpr MethodOptions_IdempotencyLevel MethodOptions_IdempotencyLevel_IdempotencyLevel_MAX = MethodOptions_IdempotencyLevel_IDEMPOTENT;
+constexpr int MethodOptions_IdempotencyLevel_IdempotencyLevel_ARRAYSIZE = MethodOptions_IdempotencyLevel_IdempotencyLevel_MAX + 1;
PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* MethodOptions_IdempotencyLevel_descriptor();
inline const ::std::string& MethodOptions_IdempotencyLevel_Name(MethodOptions_IdempotencyLevel value) {
@@ -378,8 +385,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -391,10 +397,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(FileDescriptorSet* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.FileDescriptorSet";
+ }
protected:
explicit FileDescriptorSet(::google::protobuf::Arena* arena);
private:
@@ -519,8 +529,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -532,10 +541,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(FileDescriptorProto* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.FileDescriptorProto";
+ }
protected:
explicit FileDescriptorProto(::google::protobuf::Arena* arena);
private:
@@ -849,8 +862,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -862,10 +874,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(DescriptorProto_ExtensionRange* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.DescriptorProto.ExtensionRange";
+ }
protected:
explicit DescriptorProto_ExtensionRange(::google::protobuf::Arena* arena);
private:
@@ -1006,8 +1022,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -1019,10 +1034,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(DescriptorProto_ReservedRange* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.DescriptorProto.ReservedRange";
+ }
protected:
explicit DescriptorProto_ReservedRange(::google::protobuf::Arena* arena);
private:
@@ -1150,8 +1169,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -1163,10 +1181,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(DescriptorProto* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.DescriptorProto";
+ }
protected:
explicit DescriptorProto(::google::protobuf::Arena* arena);
private:
@@ -1433,8 +1455,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -1446,10 +1467,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(ExtensionRangeOptions* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.ExtensionRangeOptions";
+ }
protected:
explicit ExtensionRangeOptions(::google::protobuf::Arena* arena);
private:
@@ -1577,8 +1602,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -1590,10 +1614,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(FieldDescriptorProto* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.FieldDescriptorProto";
+ }
protected:
explicit FieldDescriptorProto(::google::protobuf::Arena* arena);
private:
@@ -1613,50 +1641,50 @@
// nested types ----------------------------------------------------
typedef FieldDescriptorProto_Type Type;
- static const Type TYPE_DOUBLE =
+ static constexpr Type TYPE_DOUBLE =
FieldDescriptorProto_Type_TYPE_DOUBLE;
- static const Type TYPE_FLOAT =
+ static constexpr Type TYPE_FLOAT =
FieldDescriptorProto_Type_TYPE_FLOAT;
- static const Type TYPE_INT64 =
+ static constexpr Type TYPE_INT64 =
FieldDescriptorProto_Type_TYPE_INT64;
- static const Type TYPE_UINT64 =
+ static constexpr Type TYPE_UINT64 =
FieldDescriptorProto_Type_TYPE_UINT64;
- static const Type TYPE_INT32 =
+ static constexpr Type TYPE_INT32 =
FieldDescriptorProto_Type_TYPE_INT32;
- static const Type TYPE_FIXED64 =
+ static constexpr Type TYPE_FIXED64 =
FieldDescriptorProto_Type_TYPE_FIXED64;
- static const Type TYPE_FIXED32 =
+ static constexpr Type TYPE_FIXED32 =
FieldDescriptorProto_Type_TYPE_FIXED32;
- static const Type TYPE_BOOL =
+ static constexpr Type TYPE_BOOL =
FieldDescriptorProto_Type_TYPE_BOOL;
- static const Type TYPE_STRING =
+ static constexpr Type TYPE_STRING =
FieldDescriptorProto_Type_TYPE_STRING;
- static const Type TYPE_GROUP =
+ static constexpr Type TYPE_GROUP =
FieldDescriptorProto_Type_TYPE_GROUP;
- static const Type TYPE_MESSAGE =
+ static constexpr Type TYPE_MESSAGE =
FieldDescriptorProto_Type_TYPE_MESSAGE;
- static const Type TYPE_BYTES =
+ static constexpr Type TYPE_BYTES =
FieldDescriptorProto_Type_TYPE_BYTES;
- static const Type TYPE_UINT32 =
+ static constexpr Type TYPE_UINT32 =
FieldDescriptorProto_Type_TYPE_UINT32;
- static const Type TYPE_ENUM =
+ static constexpr Type TYPE_ENUM =
FieldDescriptorProto_Type_TYPE_ENUM;
- static const Type TYPE_SFIXED32 =
+ static constexpr Type TYPE_SFIXED32 =
FieldDescriptorProto_Type_TYPE_SFIXED32;
- static const Type TYPE_SFIXED64 =
+ static constexpr Type TYPE_SFIXED64 =
FieldDescriptorProto_Type_TYPE_SFIXED64;
- static const Type TYPE_SINT32 =
+ static constexpr Type TYPE_SINT32 =
FieldDescriptorProto_Type_TYPE_SINT32;
- static const Type TYPE_SINT64 =
+ static constexpr Type TYPE_SINT64 =
FieldDescriptorProto_Type_TYPE_SINT64;
static inline bool Type_IsValid(int value) {
return FieldDescriptorProto_Type_IsValid(value);
}
- static const Type Type_MIN =
+ static constexpr Type Type_MIN =
FieldDescriptorProto_Type_Type_MIN;
- static const Type Type_MAX =
+ static constexpr Type Type_MAX =
FieldDescriptorProto_Type_Type_MAX;
- static const int Type_ARRAYSIZE =
+ static constexpr int Type_ARRAYSIZE =
FieldDescriptorProto_Type_Type_ARRAYSIZE;
static inline const ::google::protobuf::EnumDescriptor*
Type_descriptor() {
@@ -1671,20 +1699,20 @@
}
typedef FieldDescriptorProto_Label Label;
- static const Label LABEL_OPTIONAL =
+ static constexpr Label LABEL_OPTIONAL =
FieldDescriptorProto_Label_LABEL_OPTIONAL;
- static const Label LABEL_REQUIRED =
+ static constexpr Label LABEL_REQUIRED =
FieldDescriptorProto_Label_LABEL_REQUIRED;
- static const Label LABEL_REPEATED =
+ static constexpr Label LABEL_REPEATED =
FieldDescriptorProto_Label_LABEL_REPEATED;
static inline bool Label_IsValid(int value) {
return FieldDescriptorProto_Label_IsValid(value);
}
- static const Label Label_MIN =
+ static constexpr Label Label_MIN =
FieldDescriptorProto_Label_Label_MIN;
- static const Label Label_MAX =
+ static constexpr Label Label_MAX =
FieldDescriptorProto_Label_Label_MAX;
- static const int Label_ARRAYSIZE =
+ static constexpr int Label_ARRAYSIZE =
FieldDescriptorProto_Label_Label_ARRAYSIZE;
static inline const ::google::protobuf::EnumDescriptor*
Label_descriptor() {
@@ -1961,8 +1989,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -1974,10 +2001,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(OneofDescriptorProto* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.OneofDescriptorProto";
+ }
protected:
explicit OneofDescriptorProto(::google::protobuf::Arena* arena);
private:
@@ -2127,8 +2158,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -2140,10 +2170,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(EnumDescriptorProto_EnumReservedRange* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.EnumDescriptorProto.EnumReservedRange";
+ }
protected:
explicit EnumDescriptorProto_EnumReservedRange(::google::protobuf::Arena* arena);
private:
@@ -2271,8 +2305,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -2284,10 +2317,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(EnumDescriptorProto* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.EnumDescriptorProto";
+ }
protected:
explicit EnumDescriptorProto(::google::protobuf::Arena* arena);
private:
@@ -2488,8 +2525,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -2501,10 +2537,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(EnumValueDescriptorProto* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.EnumValueDescriptorProto";
+ }
protected:
explicit EnumValueDescriptorProto(::google::protobuf::Arena* arena);
private:
@@ -2662,8 +2702,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -2675,10 +2714,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(ServiceDescriptorProto* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.ServiceDescriptorProto";
+ }
protected:
explicit ServiceDescriptorProto(::google::protobuf::Arena* arena);
private:
@@ -2841,8 +2884,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -2854,10 +2896,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(MethodDescriptorProto* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.MethodDescriptorProto";
+ }
protected:
explicit MethodDescriptorProto(::google::protobuf::Arena* arena);
private:
@@ -3073,8 +3119,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -3086,10 +3131,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(FileOptions* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.FileOptions";
+ }
protected:
explicit FileOptions(::google::protobuf::Arena* arena);
private:
@@ -3109,20 +3158,20 @@
// nested types ----------------------------------------------------
typedef FileOptions_OptimizeMode OptimizeMode;
- static const OptimizeMode SPEED =
+ static constexpr OptimizeMode SPEED =
FileOptions_OptimizeMode_SPEED;
- static const OptimizeMode CODE_SIZE =
+ static constexpr OptimizeMode CODE_SIZE =
FileOptions_OptimizeMode_CODE_SIZE;
- static const OptimizeMode LITE_RUNTIME =
+ static constexpr OptimizeMode LITE_RUNTIME =
FileOptions_OptimizeMode_LITE_RUNTIME;
static inline bool OptimizeMode_IsValid(int value) {
return FileOptions_OptimizeMode_IsValid(value);
}
- static const OptimizeMode OptimizeMode_MIN =
+ static constexpr OptimizeMode OptimizeMode_MIN =
FileOptions_OptimizeMode_OptimizeMode_MIN;
- static const OptimizeMode OptimizeMode_MAX =
+ static constexpr OptimizeMode OptimizeMode_MAX =
FileOptions_OptimizeMode_OptimizeMode_MAX;
- static const int OptimizeMode_ARRAYSIZE =
+ static constexpr int OptimizeMode_ARRAYSIZE =
FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE;
static inline const ::google::protobuf::EnumDescriptor*
OptimizeMode_descriptor() {
@@ -3575,8 +3624,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -3588,10 +3636,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(MessageOptions* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.MessageOptions";
+ }
protected:
explicit MessageOptions(::google::protobuf::Arena* arena);
private:
@@ -3751,8 +3803,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -3764,10 +3815,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(FieldOptions* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.FieldOptions";
+ }
protected:
explicit FieldOptions(::google::protobuf::Arena* arena);
private:
@@ -3787,20 +3842,20 @@
// nested types ----------------------------------------------------
typedef FieldOptions_CType CType;
- static const CType STRING =
+ static constexpr CType STRING =
FieldOptions_CType_STRING;
- static const CType CORD =
+ static constexpr CType CORD =
FieldOptions_CType_CORD;
- static const CType STRING_PIECE =
+ static constexpr CType STRING_PIECE =
FieldOptions_CType_STRING_PIECE;
static inline bool CType_IsValid(int value) {
return FieldOptions_CType_IsValid(value);
}
- static const CType CType_MIN =
+ static constexpr CType CType_MIN =
FieldOptions_CType_CType_MIN;
- static const CType CType_MAX =
+ static constexpr CType CType_MAX =
FieldOptions_CType_CType_MAX;
- static const int CType_ARRAYSIZE =
+ static constexpr int CType_ARRAYSIZE =
FieldOptions_CType_CType_ARRAYSIZE;
static inline const ::google::protobuf::EnumDescriptor*
CType_descriptor() {
@@ -3815,20 +3870,20 @@
}
typedef FieldOptions_JSType JSType;
- static const JSType JS_NORMAL =
+ static constexpr JSType JS_NORMAL =
FieldOptions_JSType_JS_NORMAL;
- static const JSType JS_STRING =
+ static constexpr JSType JS_STRING =
FieldOptions_JSType_JS_STRING;
- static const JSType JS_NUMBER =
+ static constexpr JSType JS_NUMBER =
FieldOptions_JSType_JS_NUMBER;
static inline bool JSType_IsValid(int value) {
return FieldOptions_JSType_IsValid(value);
}
- static const JSType JSType_MIN =
+ static constexpr JSType JSType_MIN =
FieldOptions_JSType_JSType_MIN;
- static const JSType JSType_MAX =
+ static constexpr JSType JSType_MAX =
FieldOptions_JSType_JSType_MAX;
- static const int JSType_ARRAYSIZE =
+ static constexpr int JSType_ARRAYSIZE =
FieldOptions_JSType_JSType_ARRAYSIZE;
static inline const ::google::protobuf::EnumDescriptor*
JSType_descriptor() {
@@ -3999,8 +4054,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -4012,10 +4066,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(OneofOptions* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.OneofOptions";
+ }
protected:
explicit OneofOptions(::google::protobuf::Arena* arena);
private:
@@ -4143,8 +4201,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -4156,10 +4213,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(EnumOptions* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.EnumOptions";
+ }
protected:
explicit EnumOptions(::google::protobuf::Arena* arena);
private:
@@ -4303,8 +4364,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -4316,10 +4376,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(EnumValueOptions* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.EnumValueOptions";
+ }
protected:
explicit EnumValueOptions(::google::protobuf::Arena* arena);
private:
@@ -4455,8 +4519,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -4468,10 +4531,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(ServiceOptions* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.ServiceOptions";
+ }
protected:
explicit ServiceOptions(::google::protobuf::Arena* arena);
private:
@@ -4607,8 +4674,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -4620,10 +4686,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(MethodOptions* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.MethodOptions";
+ }
protected:
explicit MethodOptions(::google::protobuf::Arena* arena);
private:
@@ -4643,20 +4713,20 @@
// nested types ----------------------------------------------------
typedef MethodOptions_IdempotencyLevel IdempotencyLevel;
- static const IdempotencyLevel IDEMPOTENCY_UNKNOWN =
+ static constexpr IdempotencyLevel IDEMPOTENCY_UNKNOWN =
MethodOptions_IdempotencyLevel_IDEMPOTENCY_UNKNOWN;
- static const IdempotencyLevel NO_SIDE_EFFECTS =
+ static constexpr IdempotencyLevel NO_SIDE_EFFECTS =
MethodOptions_IdempotencyLevel_NO_SIDE_EFFECTS;
- static const IdempotencyLevel IDEMPOTENT =
+ static constexpr IdempotencyLevel IDEMPOTENT =
MethodOptions_IdempotencyLevel_IDEMPOTENT;
static inline bool IdempotencyLevel_IsValid(int value) {
return MethodOptions_IdempotencyLevel_IsValid(value);
}
- static const IdempotencyLevel IdempotencyLevel_MIN =
+ static constexpr IdempotencyLevel IdempotencyLevel_MIN =
MethodOptions_IdempotencyLevel_IdempotencyLevel_MIN;
- static const IdempotencyLevel IdempotencyLevel_MAX =
+ static constexpr IdempotencyLevel IdempotencyLevel_MAX =
MethodOptions_IdempotencyLevel_IdempotencyLevel_MAX;
- static const int IdempotencyLevel_ARRAYSIZE =
+ static constexpr int IdempotencyLevel_ARRAYSIZE =
MethodOptions_IdempotencyLevel_IdempotencyLevel_ARRAYSIZE;
static inline const ::google::protobuf::EnumDescriptor*
IdempotencyLevel_descriptor() {
@@ -4795,8 +4865,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -4808,10 +4877,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(UninterpretedOption_NamePart* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.UninterpretedOption.NamePart";
+ }
protected:
explicit UninterpretedOption_NamePart(::google::protobuf::Arena* arena);
private:
@@ -4959,8 +5032,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -4972,10 +5044,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(UninterpretedOption* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.UninterpretedOption";
+ }
protected:
explicit UninterpretedOption(::google::protobuf::Arena* arena);
private:
@@ -5201,8 +5277,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -5214,10 +5289,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(SourceCodeInfo_Location* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.SourceCodeInfo.Location";
+ }
protected:
explicit SourceCodeInfo_Location(::google::protobuf::Arena* arena);
private:
@@ -5430,8 +5509,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -5443,10 +5521,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(SourceCodeInfo* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.SourceCodeInfo";
+ }
protected:
explicit SourceCodeInfo(::google::protobuf::Arena* arena);
private:
@@ -5573,8 +5655,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -5586,10 +5667,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(GeneratedCodeInfo_Annotation* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.GeneratedCodeInfo.Annotation";
+ }
protected:
explicit GeneratedCodeInfo_Annotation(::google::protobuf::Arena* arena);
private:
@@ -5756,8 +5841,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -5769,10 +5853,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(GeneratedCodeInfo* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.GeneratedCodeInfo";
+ }
protected:
explicit GeneratedCodeInfo(::google::protobuf::Arena* arena);
private:
diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto
index ed08fcb..87201c7 100644
--- a/src/google/protobuf/descriptor.proto
+++ b/src/google/protobuf/descriptor.proto
@@ -486,7 +486,7 @@
//
// Implementations may choose not to generate the map_entry=true message, but
// use a native map in the target language to hold the keys and values.
- // The reflection APIs in such implementions still need to work as
+ // The reflection APIs in such implementations still need to work as
// if the field is a repeated message field.
//
// NOTE: Do not set the option in .proto files. Always use the maps syntax
@@ -763,7 +763,7 @@
// beginning of the "extend" block and is shared by all extensions within
// the block.
// - Just because a location's span is a subset of some other location's span
- // does not mean that it is a descendent. For example, a "group" defines
+ // does not mean that it is a descendant. For example, a "group" defines
// both a type and a field in a single declaration. Thus, the locations
// corresponding to the type and field and their components will overlap.
// - Code which tries to interpret locations should probably be designed to
diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc
index 3ed11aa..ad32f81 100644
--- a/src/google/protobuf/descriptor_unittest.cc
+++ b/src/google/protobuf/descriptor_unittest.cc
@@ -2910,9 +2910,8 @@
ASSERT_TRUE(pool_->FindMessageTypeByName("undeclared.Quux") == NULL);
}
-INSTANTIATE_TEST_CASE_P(DatabaseSource,
- AllowUnknownDependenciesTest,
- testing::Values(NO_DATABASE, FALLBACK_DATABASE));
+INSTANTIATE_TEST_SUITE_P(DatabaseSource, AllowUnknownDependenciesTest,
+ testing::Values(NO_DATABASE, FALLBACK_DATABASE));
// ===================================================================
diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc
index 1e29f3c..ed8bcee 100644
--- a/src/google/protobuf/duration.pb.cc
+++ b/src/google/protobuf/duration.pb.cc
@@ -42,9 +42,9 @@
::google::protobuf::internal::InitSCC(&scc_info_Duration_google_2fprotobuf_2fduration_2eproto.base);
}
-::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fduration_2eproto[1];
-constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fduration_2eproto = nullptr;
-constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fduration_2eproto = nullptr;
+static ::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fduration_2eproto[1];
+static constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fduration_2eproto = nullptr;
+static constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fduration_2eproto = nullptr;
const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2fduration_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
~0u, // no _has_bits_
@@ -63,7 +63,7 @@
reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Duration_default_instance_),
};
-::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fduration_2eproto = {
+static ::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fduration_2eproto = {
{}, AddDescriptors_google_2fprotobuf_2fduration_2eproto, "google/protobuf/duration.proto", schemas,
file_default_instances, TableStruct_google_2fprotobuf_2fduration_2eproto::offsets,
file_level_metadata_google_2fprotobuf_2fduration_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2fduration_2eproto, file_level_service_descriptors_google_2fprotobuf_2fduration_2eproto,
@@ -77,7 +77,7 @@
"f/ptypes/duration\370\001\001\242\002\003GPB\252\002\036Google.Prot"
"obuf.WellKnownTypesb\006proto3"
;
-::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fduration_2eproto = {
+static ::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fduration_2eproto = {
false, InitDefaults_google_2fprotobuf_2fduration_2eproto,
descriptor_table_protodef_google_2fprotobuf_2fduration_2eproto,
"google/protobuf/duration.proto", &assign_descriptors_table_google_2fprotobuf_2fduration_2eproto, 227,
@@ -173,43 +173,36 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* Duration::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<Duration*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* Duration::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// int64 seconds = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
- msg->set_seconds(::google::protobuf::internal::ReadVarint(&ptr));
+ set_seconds(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// int32 nanos = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
- msg->set_nanos(::google::protobuf::internal::ReadVarint(&ptr));
+ set_nanos(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h
index 86c6b5b..65e147b 100644
--- a/src/google/protobuf/duration.pb.h
+++ b/src/google/protobuf/duration.pb.h
@@ -31,6 +31,13 @@
#include <google/protobuf/repeated_field.h> // IWYU pragma: export
#include <google/protobuf/extension_set.h> // IWYU pragma: export
#include <google/protobuf/unknown_field_set.h>
+namespace google {
+namespace protobuf {
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+} // namespace protobuf
+} // namespace google
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fduration_2eproto PROTOBUF_EXPORT
@@ -131,8 +138,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -144,10 +150,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Duration* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.Duration";
+ }
protected:
explicit Duration(::google::protobuf::Arena* arena);
private:
diff --git a/src/google/protobuf/dynamic_message_unittest.cc b/src/google/protobuf/dynamic_message_unittest.cc
index 94446b0..e96f658 100644
--- a/src/google/protobuf/dynamic_message_unittest.cc
+++ b/src/google/protobuf/dynamic_message_unittest.cc
@@ -316,7 +316,7 @@
delete message;
}
-INSTANTIATE_TEST_CASE_P(UseArena, DynamicMessageTest, ::testing::Bool());
+INSTANTIATE_TEST_SUITE_P(UseArena, DynamicMessageTest, ::testing::Bool());
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc
index a8d1d01..5c34b5f 100644
--- a/src/google/protobuf/empty.pb.cc
+++ b/src/google/protobuf/empty.pb.cc
@@ -42,9 +42,9 @@
::google::protobuf::internal::InitSCC(&scc_info_Empty_google_2fprotobuf_2fempty_2eproto.base);
}
-::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fempty_2eproto[1];
-constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fempty_2eproto = nullptr;
-constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fempty_2eproto = nullptr;
+static ::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fempty_2eproto[1];
+static constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fempty_2eproto = nullptr;
+static constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fempty_2eproto = nullptr;
const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2fempty_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
~0u, // no _has_bits_
@@ -61,7 +61,7 @@
reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Empty_default_instance_),
};
-::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fempty_2eproto = {
+static ::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fempty_2eproto = {
{}, AddDescriptors_google_2fprotobuf_2fempty_2eproto, "google/protobuf/empty.proto", schemas,
file_default_instances, TableStruct_google_2fprotobuf_2fempty_2eproto::offsets,
file_level_metadata_google_2fprotobuf_2fempty_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2fempty_2eproto, file_level_service_descriptors_google_2fprotobuf_2fempty_2eproto,
@@ -74,7 +74,7 @@
"/ptypes/empty\370\001\001\242\002\003GPB\252\002\036Google.Protobuf"
".WellKnownTypesb\006proto3"
;
-::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fempty_2eproto = {
+static ::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fempty_2eproto = {
false, InitDefaults_google_2fprotobuf_2fempty_2eproto,
descriptor_table_protodef_google_2fprotobuf_2fempty_2eproto,
"google/protobuf/empty.proto", &assign_descriptors_table_google_2fprotobuf_2fempty_2eproto, 183,
@@ -159,28 +159,21 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* Empty::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<Empty*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* Empty::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
default: {
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h
index f901439..58f7eec 100644
--- a/src/google/protobuf/empty.pb.h
+++ b/src/google/protobuf/empty.pb.h
@@ -31,6 +31,13 @@
#include <google/protobuf/repeated_field.h> // IWYU pragma: export
#include <google/protobuf/extension_set.h> // IWYU pragma: export
#include <google/protobuf/unknown_field_set.h>
+namespace google {
+namespace protobuf {
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+} // namespace protobuf
+} // namespace google
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fempty_2eproto PROTOBUF_EXPORT
@@ -131,8 +138,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -144,10 +150,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Empty* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.Empty";
+ }
protected:
explicit Empty(::google::protobuf::Arena* arena);
private:
diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc
index f63afef..61b5598 100644
--- a/src/google/protobuf/extension_set.cc
+++ b/src/google/protobuf/extension_set.cc
@@ -177,11 +177,7 @@
GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE ||
type == WireFormatLite::TYPE_GROUP);
ExtensionInfo info(type, is_repeated, is_packed);
-#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- info.message_info = {prototype, prototype->_ParseFunc()};
-#else
info.message_info = {prototype};
-#endif
Register(containing_type, number, info);
}
@@ -1204,9 +1200,8 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-std::pair<const char*, bool> ExtensionSet::ParseField(
- uint64 tag, ParseClosure parent, const char* begin, const char* end,
- const MessageLite* containing_type,
+const char* ExtensionSet::ParseField(
+ uint64 tag, const char* ptr, const MessageLite* containing_type,
internal::InternalMetadataWithArenaLite* metadata,
internal::ParseContext* ctx) {
GeneratedExtensionFinder finder(containing_type);
@@ -1215,12 +1210,19 @@
ExtensionInfo extension;
if (!FindExtensionInfoFromFieldNumber(tag & 7, number, &finder, &extension,
&was_packed_on_wire)) {
- return UnknownFieldParse(tag, parent, begin, end,
- metadata->mutable_unknown_fields(), ctx);
+ return UnknownFieldParse(tag, metadata->mutable_unknown_fields(), ptr, ctx);
}
return ParseFieldWithExtensionInfo(number, was_packed_on_wire, extension,
- metadata, parent, begin, end, ctx);
+ metadata, ptr, ctx);
}
+
+const char* ExtensionSet::ParseMessageSetItem(
+ const char* ptr, const MessageLite* containing_type,
+ internal::InternalMetadataWithArenaLite* metadata,
+ internal::ParseContext* ctx) {
+ return ParseMessageSetItemTmpl(ptr, containing_type, metadata, ctx);
+}
+
#endif
bool ExtensionSet::ParseFieldWithExtensionInfo(
diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h
index e5ae3d4..f29a0b5 100644
--- a/src/google/protobuf/extension_set.h
+++ b/src/google/protobuf/extension_set.h
@@ -121,9 +121,6 @@
struct MessageInfo {
const MessageLite* prototype;
-#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- ParseFunc parse_func;
-#endif
};
union {
@@ -401,33 +398,45 @@
io::CodedOutputStream* unknown_fields);
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- template <typename T>
- std::pair<const char*, bool> ParseFieldWithExtensionInfo(
- int number, bool was_packed_on_wire, const ExtensionInfo& info,
- T* metadata, ParseClosure parent, const char* begin, const char* end,
- internal::ParseContext* ctx);
// Lite parser
- std::pair<const char*, bool> ParseField(
- uint64 tag, ParseClosure parent, const char* begin, const char* end,
- const MessageLite* containing_type,
- internal::InternalMetadataWithArenaLite* metadata,
- internal::ParseContext* ctx);
+ const char* ParseField(uint64 tag, const char* ptr,
+ const MessageLite* containing_type,
+ internal::InternalMetadataWithArenaLite* metadata,
+ internal::ParseContext* ctx);
// Full parser
- std::pair<const char*, bool> ParseField(
- uint64 tag, ParseClosure parent, const char* begin, const char* end,
- const Message* containing_type,
- internal::InternalMetadataWithArena* metadata,
- internal::ParseContext* ctx);
- std::pair<const char*, bool> ParseFieldMaybeLazily(
- uint64 tag, ParseClosure parent, const char* begin, const char* end,
- const Message* containing_type,
- internal::InternalMetadataWithArena* metadata,
- internal::ParseContext* ctx);
- const char* ParseMessageSetItem(ParseClosure parent, const char* begin,
- const char* end,
- const Message* containing_type,
- internal::InternalMetadataWithArena* metadata,
- internal::ParseContext* ctx);
+ const char* ParseField(uint64 tag, const char* ptr,
+ const Message* containing_type,
+ internal::InternalMetadataWithArena* metadata,
+ internal::ParseContext* ctx);
+ template <typename Msg, typename Metadata>
+ const char* ParseMessageSet(const char* ptr, const Msg* containing_type,
+ Metadata* metadata, internal::ParseContext* ctx) {
+ struct MessageSetItem {
+ const char* _InternalParse(const char* ptr, ParseContext* ctx) {
+ return me->ParseMessageSetItem(ptr, containing_type, metadata, ctx);
+ }
+ ExtensionSet* me;
+ const Msg* containing_type;
+ Metadata* metadata;
+ } item{this, containing_type, metadata};
+ while (!ctx->Done(&ptr)) {
+ uint32 tag;
+ ptr = ReadTag(ptr, &tag);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ if (tag == WireFormatLite::kMessageSetItemStartTag) {
+ ptr = ctx->ParseGroup(&item, ptr, tag);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ } else {
+ if (tag == 0 || (tag & 7) == 4) {
+ ctx->SetLastTag(tag);
+ return ptr;
+ }
+ ptr = ParseField(tag, ptr, containing_type, metadata, ctx);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ }
+ }
+ return ptr;
+ }
#endif
// Parse an entire message in MessageSet format. Such messages have no
@@ -527,6 +536,9 @@
virtual bool ReadMessage(const MessageLite& prototype,
io::CodedInputStream* input) = 0;
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+ virtual const char* _InternalParse(const char* ptr, ParseContext* ctx) = 0;
+#endif
virtual void WriteMessage(int number,
io::CodedOutputStream* output) const = 0;
virtual uint8* WriteMessageToArray(int number, uint8* target) const = 0;
@@ -697,13 +709,6 @@
// Merges existing Extension from other_extension
void InternalExtensionMergeFrom(int number, const Extension& other_extension);
-#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- bool FindExtension(int wire_type, uint32 field,
- const Message* containing_type,
- const internal::ParseContext* ctx,
- ExtensionInfo* extension, bool* was_packed_on_wire);
-#endif
-
// Returns true and fills field_number and extension if extension is found.
// Note to support packed repeated field compatibility, it also fills whether
// the tag on wire is packed, which can be different from
@@ -757,6 +762,53 @@
ExtensionFinder* extension_finder,
MessageSetFieldSkipper* field_skipper);
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+ bool FindExtension(int wire_type, uint32 field,
+ const MessageLite* containing_type,
+ const internal::ParseContext* ctx,
+ ExtensionInfo* extension, bool* was_packed_on_wire) {
+ GeneratedExtensionFinder finder(containing_type);
+ return FindExtensionInfoFromFieldNumber(wire_type, field, &finder,
+ extension, was_packed_on_wire);
+ }
+ inline bool FindExtension(int wire_type, uint32 field,
+ const Message* containing_type,
+ const internal::ParseContext* ctx,
+ ExtensionInfo* extension, bool* was_packed_on_wire);
+ // Used for MessageSet only
+ const char* ParseFieldMaybeLazily(
+ uint64 tag, const char* ptr, const MessageLite* containing_type,
+ internal::InternalMetadataWithArenaLite* metadata,
+ internal::ParseContext* ctx) {
+ // Lite MessageSet doesn't implement lazy.
+ return ParseField(tag, ptr, containing_type, metadata, ctx);
+ }
+ const char* ParseFieldMaybeLazily(
+ uint64 tag, const char* ptr, const Message* containing_type,
+ internal::InternalMetadataWithArena* metadata,
+ internal::ParseContext* ctx);
+ const char* ParseMessageSetItem(
+ const char* ptr, const MessageLite* containing_type,
+ internal::InternalMetadataWithArenaLite* metadata,
+ internal::ParseContext* ctx);
+ const char* ParseMessageSetItem(const char* ptr,
+ const Message* containing_type,
+ internal::InternalMetadataWithArena* metadata,
+ internal::ParseContext* ctx);
+
+ // Implemented in extension_set_inl.h to keep code out of the header file.
+ template <typename T>
+ const char* ParseFieldWithExtensionInfo(int number, bool was_packed_on_wire,
+ const ExtensionInfo& info,
+ T* metadata, const char* ptr,
+ internal::ParseContext* ctx);
+ template <typename Msg, typename Metadata>
+ const char* ParseMessageSetItemTmpl(const char* ptr,
+ const Msg* containing_type,
+ Metadata* metadata,
+ internal::ParseContext* ctx);
+#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
// Hack: RepeatedPtrFieldBase declares ExtensionSet as a friend. This
// friendship should automatically extend to ExtensionSet::Extension, but
// unfortunately some older compilers (e.g. GCC 3.4.4) do not implement this
@@ -804,44 +856,6 @@
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet);
};
-#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-
-template <typename Msg, typename Metadata>
-const char* ParseMessageSet(const char* begin, const char* end, Msg* msg,
- ExtensionSet* ext, Metadata* metadata,
- internal::ParseContext* ctx) {
- auto ptr = begin;
- int depth = 0;
- while (ptr < end) {
- uint32 tag;
- ptr = io::Parse32(ptr, &tag);
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- if (tag == WireFormatLite::kMessageSetItemStartTag) {
- ctx->extra_parse_data().payload.clear();
- auto res = ctx->ParseGroup(tag, {Msg::InternalParseMessageSetItem, msg},
- ptr, end, &depth);
- ptr = res.first;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- if (res.second) {
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->StoreGroup(
- {Msg::_InternalParse, msg}, {Msg::InternalParseMessageSetItem, msg},
- depth, tag));
- return ptr;
- }
- } else {
- auto res =
- ext->ParseField(tag, {Msg::_InternalParse, msg}, ptr, end,
- Msg::internal_default_instance(), metadata, ctx);
- ptr = res.first;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- if (res.second) break;
- }
- }
- return ptr;
-}
-
-#endif
-
// These are just for convenience...
inline void ExtensionSet::SetString(int number, FieldType type,
const std::string& value,
diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc
index 3642250..53aec2b 100644
--- a/src/google/protobuf/extension_set_heavy.cc
+++ b/src/google/protobuf/extension_set_heavy.cc
@@ -309,10 +309,6 @@
GOOGLE_CHECK(output->message_info.prototype != nullptr)
<< "Extension factory's GetPrototype() returned NULL for extension: "
<< extension->full_name();
-#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- output->message_info.parse_func =
- output->message_info.prototype->_ParseFunc();
-#endif
} else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
output->enum_validity_check.func = ValidateEnumUsingDescriptor;
output->enum_validity_check.arg = extension->enum_type();
@@ -329,15 +325,14 @@
const internal::ParseContext* ctx,
ExtensionInfo* extension,
bool* was_packed_on_wire) {
- if (ctx->extra_parse_data().pool == nullptr) {
+ if (ctx->data().pool == nullptr) {
GeneratedExtensionFinder finder(containing_type);
if (!FindExtensionInfoFromFieldNumber(wire_type, field, &finder, extension,
was_packed_on_wire)) {
return false;
}
} else {
- DescriptorPoolExtensionFinder finder(ctx->extra_parse_data().pool,
- ctx->extra_parse_data().factory,
+ DescriptorPoolExtensionFinder finder(ctx->data().pool, ctx->data().factory,
containing_type->GetDescriptor());
if (!FindExtensionInfoFromFieldNumber(wire_type, field, &finder, extension,
was_packed_on_wire)) {
@@ -347,9 +342,8 @@
return true;
}
-std::pair<const char*, bool> ExtensionSet::ParseField(
- uint64 tag, ParseClosure parent, const char* begin, const char* end,
- const Message* containing_type,
+const char* ExtensionSet::ParseField(
+ uint64 tag, const char* ptr, const Message* containing_type,
internal::InternalMetadataWithArena* metadata,
internal::ParseContext* ctx) {
int number = tag >> 3;
@@ -357,20 +351,26 @@
ExtensionInfo extension;
if (!FindExtension(tag & 7, number, containing_type, ctx, &extension,
&was_packed_on_wire)) {
- return UnknownFieldParse(tag, parent, begin, end,
- metadata->mutable_unknown_fields(), ctx);
+ return UnknownFieldParse(tag, metadata->mutable_unknown_fields(), ptr, ctx);
}
return ParseFieldWithExtensionInfo(number, was_packed_on_wire, extension,
- metadata, parent, begin, end, ctx);
+ metadata, ptr, ctx);
}
-std::pair<const char*, bool> ExtensionSet::ParseFieldMaybeLazily(
- uint64 tag, ParseClosure parent, const char* begin, const char* end,
- const Message* containing_type,
+const char* ExtensionSet::ParseFieldMaybeLazily(
+ uint64 tag, const char* ptr, const Message* containing_type,
internal::InternalMetadataWithArena* metadata,
internal::ParseContext* ctx) {
- return ParseField(tag, parent, begin, end, containing_type, metadata, ctx);
+ return ParseField(tag, ptr, containing_type, metadata, ctx);
}
+
+const char* ExtensionSet::ParseMessageSetItem(
+ const char* ptr, const Message* containing_type,
+ internal::InternalMetadataWithArena* metadata,
+ internal::ParseContext* ctx) {
+ return ParseMessageSetItemTmpl(ptr, containing_type, metadata, ctx);
+}
+
#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
@@ -388,83 +388,6 @@
}
}
-#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* ExtensionSet::ParseMessageSetItem(
- ParseClosure parent, const char* begin, const char* end,
- const Message* containing_type,
- internal::InternalMetadataWithArena* metadata,
- internal::ParseContext* ctx) {
- auto ptr = begin;
- while (ptr < end) {
- uint32 tag = *ptr++;
- if (tag == WireFormatLite::kMessageSetTypeIdTag) {
- uint32 type_id;
- ptr = io::Parse32(ptr, &type_id);
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-
- if (ctx->extra_parse_data().payload.empty()) {
- tag = *ptr++;
- GOOGLE_PROTOBUF_PARSER_ASSERT(tag ==
- WireFormatLite::kMessageSetMessageTag);
- auto res =
- ParseFieldMaybeLazily(static_cast<uint64>(type_id) * 8 + 2, parent,
- ptr, end, containing_type, metadata, ctx);
- ptr = res.first;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) break;
- } else {
- ExtensionInfo extension;
- bool was_packed_on_wire;
- if (!FindExtension(2, type_id, containing_type, ctx, &extension,
- &was_packed_on_wire)) {
- metadata->mutable_unknown_fields()->AddLengthDelimited(
- type_id, ctx->extra_parse_data().payload);
- continue;
- }
- MessageLite* value =
- extension.is_repeated
- ? AddMessage(type_id, WireFormatLite::TYPE_MESSAGE,
- *extension.message_info.prototype,
- extension.descriptor)
- : MutableMessage(type_id, WireFormatLite::TYPE_MESSAGE,
- *extension.message_info.prototype,
- extension.descriptor);
- ParseClosure parser = {extension.message_info.parse_func, value};
- StringPiece chunk(ctx->extra_parse_data().payload);
- bool ok = ctx->ParseExactRange(parser, chunk.begin(), chunk.end());
- GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
- }
- } else if (tag == WireFormatLite::kMessageSetItemEndTag) {
- ctx->EndGroup(tag);
- break;
- } else if (tag == WireFormatLite::kMessageSetMessageTag) {
- uint32 size;
- ptr = io::Parse32(ptr, &size);
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ParseClosure child = {internal::StringParser,
- &ctx->extra_parse_data().payload};
- if (size > end - ptr + internal::ParseContext::kSlopBytes) {
- ctx->extra_parse_data().payload.clear();
- return ctx->StoreAndTailCall(ptr, end, parent, child, size);
- } else {
- ctx->extra_parse_data().payload.assign(ptr, size);
- ptr += size;
- }
- } else {
- ptr--;
- ptr = io::Parse32(ptr, &tag);
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- auto res =
- ParseField(tag, parent, ptr, end, containing_type, metadata, ctx);
- ptr = res.first;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- if (res.second) break;
- }
- }
- return ptr;
-}
-#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-
bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
const Message* containing_type,
UnknownFieldSet* unknown_fields) {
diff --git a/src/google/protobuf/extension_set_inl.h b/src/google/protobuf/extension_set_inl.h
index ed9f19c..b73913a 100644
--- a/src/google/protobuf/extension_set_inl.h
+++ b/src/google/protobuf/extension_set_inl.h
@@ -31,6 +31,7 @@
#ifndef GOOGLE_PROTOBUF_EXTENSION_SET_INL_H__
#define GOOGLE_PROTOBUF_EXTENSION_SET_INL_H__
+#include <google/protobuf/parse_context.h>
#include <google/protobuf/extension_set.h>
namespace google {
@@ -39,22 +40,17 @@
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
template <typename T>
-std::pair<const char*, bool> ExtensionSet::ParseFieldWithExtensionInfo(
+const char* ExtensionSet::ParseFieldWithExtensionInfo(
int number, bool was_packed_on_wire, const ExtensionInfo& extension,
- T* metadata, ParseClosure parent, const char* begin, const char* end,
- internal::ParseContext* ctx) {
- auto ptr = begin;
- ParseClosure child;
- int depth;
+ T* metadata, const char* ptr, internal::ParseContext* ctx) {
if (was_packed_on_wire) {
switch (extension.type) {
#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE) \
case WireFormatLite::TYPE_##UPPERCASE: \
- child = { \
- internal::Packed##CPP_CAMELCASE##Parser, \
+ return internal::Packed##CPP_CAMELCASE##Parser( \
MutableRawRepeatedField(number, extension.type, extension.is_packed, \
- extension.descriptor)}; \
- goto length_delim
+ extension.descriptor), \
+ ptr, ctx);
HANDLE_TYPE(INT32, Int32);
HANDLE_TYPE(INT64, Int64);
HANDLE_TYPE(UINT32, UInt32);
@@ -71,15 +67,12 @@
#undef HANDLE_TYPE
case WireFormatLite::TYPE_ENUM:
- ctx->extra_parse_data().SetEnumValidatorArg(
- extension.enum_validity_check.func,
+ return internal::PackedEnumParserArg(
+ MutableRawRepeatedField(number, extension.type, extension.is_packed,
+ extension.descriptor),
+ ptr, ctx, extension.enum_validity_check.func,
extension.enum_validity_check.arg,
metadata->mutable_unknown_fields(), number);
- child = {
- internal::PackedValidEnumParserLiteArg,
- MutableRawRepeatedField(number, extension.type, extension.is_packed,
- extension.descriptor)};
- goto length_delim;
case WireFormatLite::TYPE_STRING:
case WireFormatLite::TYPE_BYTES:
case WireFormatLite::TYPE_GROUP:
@@ -92,8 +85,8 @@
#define HANDLE_VARINT_TYPE(UPPERCASE, CPP_CAMELCASE) \
case WireFormatLite::TYPE_##UPPERCASE: { \
uint64 value; \
- ptr = io::Parse64(ptr, &value); \
- GOOGLE_PROTOBUF_ASSERT_RETURN(ptr, std::make_pair(nullptr, true)); \
+ ptr = ParseVarint64(ptr, &value); \
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); \
if (extension.is_repeated) { \
Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
extension.is_packed, value, extension.descriptor); \
@@ -111,8 +104,8 @@
#define HANDLE_SVARINT_TYPE(UPPERCASE, CPP_CAMELCASE, SIZE) \
case WireFormatLite::TYPE_##UPPERCASE: { \
uint64 val; \
- ptr = io::Parse64(ptr, &val); \
- GOOGLE_PROTOBUF_ASSERT_RETURN(ptr, std::make_pair(nullptr, true)); \
+ ptr = ParseVarint64(ptr, &val); \
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); \
auto value = WireFormatLite::ZigZagDecode##SIZE(val); \
if (extension.is_repeated) { \
Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
@@ -151,8 +144,8 @@
case WireFormatLite::TYPE_ENUM: {
uint64 val;
- ptr = io::Parse64(ptr, &val);
- GOOGLE_PROTOBUF_ASSERT_RETURN(ptr, std::make_pair(nullptr, true));
+ ptr = ParseVarint64(ptr, &val);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
int value = val;
if (!extension.enum_validity_check.func(
@@ -175,8 +168,9 @@
extension.descriptor)
: MutableString(number, WireFormatLite::TYPE_STRING,
extension.descriptor);
- child = {StringParser, value};
- goto length_delim;
+ int size = ReadSize(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ return ctx->ReadString(ptr, size, value);
}
case WireFormatLite::TYPE_GROUP: {
@@ -188,18 +182,8 @@
: MutableMessage(number, WireFormatLite::TYPE_GROUP,
*extension.message_info.prototype,
extension.descriptor);
- child = {extension.message_info.parse_func, value};
uint32 tag = (number << 3) + WireFormatLite::WIRETYPE_START_GROUP;
- auto res = ctx->ParseGroup(tag, child, ptr, end, &depth);
- ptr = res.first;
- GOOGLE_PROTOBUF_ASSERT_RETURN(ptr, std::make_pair(nullptr, true));
- if (res.second) {
- GOOGLE_PROTOBUF_ASSERT_RETURN(
- ctx->StoreGroup(parent, child, depth, tag),
- std::make_pair(nullptr, true));
- return std::make_pair(ptr, true);
- }
- break;
+ return ctx->ParseGroup(value, ptr, tag);
}
case WireFormatLite::TYPE_MESSAGE: {
@@ -211,31 +195,77 @@
: MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
*extension.message_info.prototype,
extension.descriptor);
- child = {extension.message_info.parse_func, value};
- goto length_delim;
+ return ctx->ParseMessage(value, ptr);
}
}
}
-
- return std::make_pair(ptr, false);
-
-length_delim:
- uint32 size;
- ptr = io::Parse32(ptr, &size);
- GOOGLE_PROTOBUF_ASSERT_RETURN(ptr, std::make_pair(nullptr, true));
- if (size > end - ptr) goto len_delim_till_end;
- {
- auto newend = ptr + size;
- bool ok = ctx->ParseExactRange(child, ptr, newend);
- GOOGLE_PROTOBUF_ASSERT_RETURN(ok, std::make_pair(nullptr, true));
- ptr = newend;
- }
- return std::make_pair(ptr, false);
-len_delim_till_end:
- return std::make_pair(ctx->StoreAndTailCall(ptr, end, parent, child, size),
- true);
+ return ptr;
}
-#endif
+
+template <typename Msg, typename Metadata>
+const char* ExtensionSet::ParseMessageSetItemTmpl(const char* ptr,
+ const Msg* containing_type,
+ Metadata* metadata,
+ internal::ParseContext* ctx) {
+ std::string payload;
+ uint32 type_id = 0;
+ while (!ctx->Done(&ptr)) {
+ uint32 tag;
+ ptr = ReadTag(ptr, &tag);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ if (tag == WireFormatLite::kMessageSetTypeIdTag) {
+ ptr = _Parse32(ptr, &type_id);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ if (!payload.empty()) {
+ ExtensionInfo extension;
+ bool was_packed_on_wire;
+ if (!FindExtension(2, type_id, containing_type, ctx, &extension,
+ &was_packed_on_wire)) {
+ WriteLengthDelimited(type_id, payload,
+ metadata->mutable_unknown_fields());
+ } else {
+ MessageLite* value =
+ extension.is_repeated
+ ? AddMessage(type_id, WireFormatLite::TYPE_MESSAGE,
+ *extension.message_info.prototype,
+ extension.descriptor)
+ : MutableMessage(type_id, WireFormatLite::TYPE_MESSAGE,
+ *extension.message_info.prototype,
+ extension.descriptor);
+
+ const char* p;
+ ParseContext tmp_ctx(ctx->depth(), false, &p, payload);
+ tmp_ctx.data().pool = ctx->data().pool;
+ tmp_ctx.data().factory = ctx->data().factory;
+ GOOGLE_PROTOBUF_PARSER_ASSERT(
+ tmp_ctx.AtLegitimateEnd(value->_InternalParse(p, &tmp_ctx)));
+ }
+ type_id = 0;
+ }
+ } else if (tag == WireFormatLite::kMessageSetMessageTag) {
+ if (type_id != 0) {
+ ptr = ParseFieldMaybeLazily(static_cast<uint64>(type_id) * 8 + 2, ptr,
+ containing_type, metadata, ctx);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+ type_id = 0;
+ } else {
+ int32 size = ReadSize(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ ptr = ctx->ReadString(ptr, size, &payload);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ }
+ } else {
+ if (tag == 0 || (tag & 7) == 4) {
+ ctx->SetLastTag(tag);
+ return ptr;
+ }
+ ptr = ParseField(tag, ptr, containing_type, metadata, ctx);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ }
+ }
+ return ptr;
+}
+#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
} // namespace internal
} // namespace protobuf
diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc
index e5a8fe6..0607b91 100644
--- a/src/google/protobuf/field_mask.pb.cc
+++ b/src/google/protobuf/field_mask.pb.cc
@@ -42,9 +42,9 @@
::google::protobuf::internal::InitSCC(&scc_info_FieldMask_google_2fprotobuf_2ffield_5fmask_2eproto.base);
}
-::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2ffield_5fmask_2eproto[1];
-constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto = nullptr;
-constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto = nullptr;
+static ::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2ffield_5fmask_2eproto[1];
+static constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto = nullptr;
+static constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto = nullptr;
const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
~0u, // no _has_bits_
@@ -62,7 +62,7 @@
reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_FieldMask_default_instance_),
};
-::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2ffield_5fmask_2eproto = {
+static ::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2ffield_5fmask_2eproto = {
{}, AddDescriptors_google_2fprotobuf_2ffield_5fmask_2eproto, "google/protobuf/field_mask.proto", schemas,
file_default_instances, TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto::offsets,
file_level_metadata_google_2fprotobuf_2ffield_5fmask_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto, file_level_service_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto,
@@ -76,7 +76,7 @@
"ield_mask;field_mask\370\001\001\242\002\003GPB\252\002\036Google.P"
"rotobuf.WellKnownTypesb\006proto3"
;
-::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto = {
+static ::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto = {
false, InitDefaults_google_2fprotobuf_2ffield_5fmask_2eproto,
descriptor_table_protodef_google_2fprotobuf_2ffield_5fmask_2eproto,
"google/protobuf/field_mask.proto", &assign_descriptors_table_google_2fprotobuf_2ffield_5fmask_2eproto, 230,
@@ -167,59 +167,36 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* FieldMask::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<FieldMask*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* FieldMask::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// repeated string paths = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(add_paths(), ptr, ctx, "google.protobuf.FieldMask.paths");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.FieldMask.paths");
- object = msg->add_paths();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool FieldMask::MergePartialFromCodedStream(
diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h
index a74e3b4..02e629d 100644
--- a/src/google/protobuf/field_mask.pb.h
+++ b/src/google/protobuf/field_mask.pb.h
@@ -31,6 +31,13 @@
#include <google/protobuf/repeated_field.h> // IWYU pragma: export
#include <google/protobuf/extension_set.h> // IWYU pragma: export
#include <google/protobuf/unknown_field_set.h>
+namespace google {
+namespace protobuf {
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+} // namespace protobuf
+} // namespace google
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ffield_5fmask_2eproto PROTOBUF_EXPORT
@@ -131,8 +138,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -144,10 +150,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(FieldMask* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.FieldMask";
+ }
protected:
explicit FieldMask(::google::protobuf::Arena* arena);
private:
diff --git a/src/google/protobuf/generated_message_table_driven.h b/src/google/protobuf/generated_message_table_driven.h
index 8fee7ab..d06a260 100644
--- a/src/google/protobuf/generated_message_table_driven.h
+++ b/src/google/protobuf/generated_message_table_driven.h
@@ -209,15 +209,12 @@
// The tables must be composed of POD components to ensure link-time
// initialization.
static_assert(std::is_pod<ParseTableField>::value, "");
+static_assert(std::is_pod<AuxillaryParseTableField>::value, "");
static_assert(std::is_pod<AuxillaryParseTableField::enum_aux>::value, "");
static_assert(std::is_pod<AuxillaryParseTableField::message_aux>::value, "");
static_assert(std::is_pod<AuxillaryParseTableField::string_aux>::value, "");
static_assert(std::is_pod<ParseTable>::value, "");
-#ifndef __NVCC__ // This assertion currently fails under NVCC.
-static_assert(std::is_pod<AuxillaryParseTableField>::value, "");
-#endif
-
// TODO(ckennelly): Consolidate these implementations into a single one, using
// dynamic dispatch to the appropriate unknown field handler.
bool MergePartialFromCodedStream(MessageLite* msg, const ParseTable& table,
diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h
index 6230153..8003d17 100644
--- a/src/google/protobuf/generated_message_util.h
+++ b/src/google/protobuf/generated_message_util.h
@@ -44,9 +44,9 @@
#include <string>
#include <vector>
-#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/parse_context.h>
+#include <google/protobuf/arenastring.h>
#include <google/protobuf/has_bits.h>
#include <google/protobuf/implicit_weak_message.h>
#include <google/protobuf/message_lite.h>
@@ -218,31 +218,6 @@
OnShutdownRun(DestroyString, ptr);
}
-#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-// To simplify generation of the parse loop code we take objects by void ptr.
-inline void InlineGreedyStringParser(void* str, const char* begin, int size,
- ParseContext*) {
- static_cast<std::string*>(str)->assign(begin, size);
-}
-
-
-inline bool StringCheck(const char* begin, int size, ParseContext* ctx) {
- return true;
-}
-
-inline bool StringCheckUTF8(const char* begin, int size, ParseContext* ctx) {
- return VerifyUTF8(StringPiece(begin, size), ctx);
-}
-
-inline bool StringCheckUTF8Verify(const char* begin, int size,
- ParseContext* ctx) {
-#ifndef NDEBUG
- VerifyUTF8(StringPiece(begin, size), ctx);
-#endif
- return true;
-}
-
-#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
} // namespace internal
} // namespace protobuf
diff --git a/src/google/protobuf/implicit_weak_message.cc b/src/google/protobuf/implicit_weak_message.cc
index 5cc718f..4cd0968 100644
--- a/src/google/protobuf/implicit_weak_message.cc
+++ b/src/google/protobuf/implicit_weak_message.cc
@@ -48,11 +48,9 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* ImplicitWeakMessage::_InternalParse(const char* begin,
- const char* end, void* object,
+const char* ImplicitWeakMessage::_InternalParse(const char* ptr,
ParseContext* ctx) {
- return internal::StringParser(
- begin, end, &(static_cast<ImplicitWeakMessage*>(object)->data_), ctx);
+ return ctx->AppendString(ptr, &data_);
}
#endif
diff --git a/src/google/protobuf/implicit_weak_message.h b/src/google/protobuf/implicit_weak_message.h
index 5d3b479..16b9164 100644
--- a/src/google/protobuf/implicit_weak_message.h
+++ b/src/google/protobuf/implicit_weak_message.h
@@ -79,10 +79,7 @@
bool MergePartialFromCodedStream(io::CodedInputStream* input) override;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- ParseFunc _ParseFunc() const override { return _InternalParse; }
-
- static const char* _InternalParse(const char* begin, const char* end,
- void* object, ParseContext* ctx);
+ const char* _InternalParse(const char* ptr, ParseContext* ctx) final;
#endif
size_t ByteSizeLong() const override { return data_.size(); }
diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h
index d75095d..740571b 100644
--- a/src/google/protobuf/io/coded_stream.h
+++ b/src/google/protobuf/io/coded_stream.h
@@ -144,8 +144,12 @@
class DescriptorPool;
class MessageFactory;
+class ZeroCopyCodedInputStream;
-namespace internal { void MapTestForceDeterministic(); }
+namespace internal {
+void MapTestForceDeterministic();
+class EpsCopyByteStream;
+} // namespace internal
namespace io {
@@ -157,64 +161,6 @@
class ZeroCopyInputStream; // zero_copy_stream.h
class ZeroCopyOutputStream; // zero_copy_stream.h
-template <typename T>
-T UnalignedLoad(const void* p) {
- T res;
- memcpy(&res, p, sizeof(T));
- return res;
-}
-
-// TODO(gerbens) Experiment with best implementation.
-// Clang unrolls loop and generating pretty good code on O2, gcc doesn't.
-// Unclear if we want 64 bit parse loop unrolled, inlined or opaque function
-// call. Hence experimentation is needed.
-// Important guarantee is that it doesn't read more than size bytes from p.
-template <int size, typename T>
-const char* VarintParse(const char* p, T* out) {
- T res = 0;
- T extra = 0;
- for (int i = 0; i < size; i++) {
- T byte = static_cast<uint8>(p[i]);
- res += byte << (i * 7);
- int j = i + 1;
- if (PROTOBUF_PREDICT_TRUE(byte < 128)) {
- *out = res - extra;
- return p + j;
- }
- extra += 128ull << (i * 7);
- }
- *out = 0;
- return nullptr;
-}
-
-inline const char* Parse32(const char* p, uint32* out) {
- return VarintParse<5>(p, out);
-}
-inline const char* Parse64(const char* p, uint64* out) {
- return VarintParse<10>(p, out);
-}
-
-inline const char* ReadSize(const char* p, int32* out) {
- int32 res = 0;
- int32 extra = 0;
- for (int i = 0; i < 4; i++) {
- uint32 byte = static_cast<uint8>(p[i]);
- res += byte << (i * 7);
- int j = i + 1;
- if (PROTOBUF_PREDICT_TRUE(byte < 128)) {
- *out = res - extra;
- return p + j;
- }
- extra += 128ull << (i * 7);
- }
- uint32 byte = static_cast<uint8>(p[4]);
- // size may not be negative, so only the lowest 3 bits can be set.
- if (byte >= 8) return nullptr;
- res += byte << (4 * 7);
- *out = res - extra;
- return p + 5;
-}
-
// Class which reads and decodes binary data which is composed of varint-
// encoded integers and fixed-width pieces. Wraps a ZeroCopyInputStream.
// Most users will not need to deal with CodedInputStream.
@@ -693,6 +639,9 @@
static const int kDefaultTotalBytesLimit = INT_MAX;
static int default_recursion_limit_; // 100 by default.
+
+ friend class google::protobuf::ZeroCopyCodedInputStream;
+ friend class google::protobuf::internal::EpsCopyByteStream;
};
// Class which encodes and writes binary data which is composed of varint-
diff --git a/src/google/protobuf/io/zero_copy_stream_impl.cc b/src/google/protobuf/io/zero_copy_stream_impl.cc
index dd92113..ea18ae6 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl.cc
+++ b/src/google/protobuf/io/zero_copy_stream_impl.cc
@@ -78,7 +78,6 @@
} // namespace
-
// ===================================================================
FileInputStream::FileInputStream(int file_descriptor, int block_size)
diff --git a/src/google/protobuf/io/zero_copy_stream_impl.h b/src/google/protobuf/io/zero_copy_stream_impl.h
index 90d9380..ea8681b 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl.h
+++ b/src/google/protobuf/io/zero_copy_stream_impl.h
@@ -53,7 +53,6 @@
namespace protobuf {
namespace io {
-
// ===================================================================
// A ZeroCopyInputStream which reads from a file descriptor.
diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h
index 624f84d..40f35e9 100644
--- a/src/google/protobuf/map.h
+++ b/src/google/protobuf/map.h
@@ -414,7 +414,7 @@
: node_(NodePtrFromKeyPtr(*tree_it)), m_(m), bucket_index_(index) {
// Invariant: iterators that use buckets with trees have an even
// bucket_index_.
- GOOGLE_DCHECK_EQ(bucket_index_ % 2, 0);
+ GOOGLE_DCHECK_EQ(bucket_index_ % 2, 0u);
}
// Advance through buckets, looking for the first that isn't empty.
@@ -454,7 +454,7 @@
if (is_list) {
SearchFrom(bucket_index_ + 1);
} else {
- GOOGLE_DCHECK_EQ(bucket_index_ & 1, 0);
+ GOOGLE_DCHECK_EQ(bucket_index_ & 1, 0u);
Tree* tree = static_cast<Tree*>(m_->table_[bucket_index_]);
if (++tree_it == tree->end()) {
SearchFrom(bucket_index_ + 2);
diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h
index 2b36b0b..5ebc82a 100644
--- a/src/google/protobuf/map_entry_lite.h
+++ b/src/google/protobuf/map_entry_lite.h
@@ -36,6 +36,7 @@
#include <google/protobuf/stubs/casts.h>
#include <google/protobuf/parse_context.h>
+#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/map.h>
@@ -193,6 +194,31 @@
MergeFromInternal(*::google::protobuf::down_cast<const Derived*>(&other));
}
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+ const char* _InternalParse(const char* ptr, ParseContext* ctx) final {
+ while (!ctx->Done(&ptr)) {
+ uint32 tag;
+ ptr = ReadTag(ptr, &tag);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ if (tag == kKeyTag) {
+ set_has_key();
+ ptr = KeyTypeHandler::Read(ptr, ctx, mutable_key());
+ } else if (tag == kValueTag) {
+ set_has_value();
+ ptr = ValueTypeHandler::Read(ptr, ctx, mutable_value());
+ } else {
+ if (tag == 0 || WireFormatLite::GetTagWireType(tag) ==
+ WireFormatLite::WIRETYPE_END_GROUP) {
+ ctx->SetLastTag(tag);
+ return ptr;
+ }
+ ptr = UnknownFieldParse(tag, nullptr, ptr, ctx);
+ }
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ }
+ return ptr;
+ }
+#else
bool MergePartialFromCodedStream(io::CodedInputStream* input) override {
uint32 tag;
@@ -233,6 +259,7 @@
}
}
}
+#endif
size_t ByteSizeLong() const override {
size_t size = 0;
@@ -386,35 +413,12 @@
return result;
}
-#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- bool ParseMap(const char* begin, const char* end) {
- io::CodedInputStream input(reinterpret_cast<const uint8*>(begin),
- end - begin);
- return MergePartialFromCodedStream(&input) &&
- input.ConsumedEntireMessage();
- }
- template <typename Metadata>
- bool ParseMapEnumValidation(const char* begin, const char* end, uint32 num,
- Metadata* metadata,
- bool (*validate_enum)(int)) {
- io::CodedInputStream input(reinterpret_cast<const uint8*>(begin),
- static_cast<int>(end - begin));
+ const char* _InternalParse(const char* ptr, ParseContext* ctx) {
auto entry = NewEntry();
- // TODO(gerbens) implement _InternalParse for maps. We can't use
- // ParseFromString as this will call _InternalParse
- if (!(entry->MergePartialFromCodedStream(&input) &&
- input.ConsumedEntireMessage()))
- return false;
- if (!validate_enum(entry->value())) {
- auto unknown_fields = metadata->mutable_unknown_fields();
- WriteLengthDelimited(num, StringPiece(begin, end - begin),
- unknown_fields);
- return true;
- }
- (*map_)[entry->key()] = static_cast<Value>(entry->value());
- return true;
+ ptr = entry->_InternalParse(ptr, ctx);
+ UseKeyAndValueFromEntry();
+ return ptr;
}
-#endif
MapEntryImpl* NewEntry() { return entry_ = mf_->NewEntry(); }
@@ -425,7 +429,7 @@
const Value& entry_value() const { return entry_->value(); }
private:
- void UseKeyAndValueFromEntry() PROTOBUF_COLD {
+ void UseKeyAndValueFromEntry() {
// Update key_ in case we need it later (because key() is called).
// This is potentially inefficient, especially if the key is
// expensive to copy (e.g., a long string), but this is a cold
@@ -477,7 +481,7 @@
bool has_value() const { return (_has_bits_[0] & 0x00000002u) != 0; }
void clear_has_value() { _has_bits_[0] &= ~0x00000002u; }
- private:
+ public:
// Serializing a generated message containing map field involves serializing
// key-value pairs from Map. The wire format of each key-value pair
// after serialization should be the same as that of a MapEntry message
diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h
index ef1804b..91be966 100644
--- a/src/google/protobuf/map_field.h
+++ b/src/google/protobuf/map_field.h
@@ -288,6 +288,10 @@
return impl_.NewEntryWrapper(key, t);
}
+ const char* _InternalParse(const char* ptr, ParseContext* ctx) {
+ return impl_._InternalParse(ptr, ctx);
+ }
+
private:
MapFieldLiteType impl_;
diff --git a/src/google/protobuf/map_field_lite.h b/src/google/protobuf/map_field_lite.h
index 5b8d2e4..4e5f898 100644
--- a/src/google/protobuf/map_field_lite.h
+++ b/src/google/protobuf/map_field_lite.h
@@ -32,6 +32,7 @@
#define GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
#include <type_traits>
+#include <google/protobuf/parse_context.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/map.h>
#include <google/protobuf/map_entry_lite.h>
@@ -108,6 +109,11 @@
return EntryType::Wrap(key, t, arena_);
}
+ const char* _InternalParse(const char* ptr, ParseContext* ctx) {
+ typename Derived::template Parser<MapFieldLite, Map<Key, T>> parser(this);
+ return parser._InternalParse(ptr, ctx);
+ }
+
private:
typedef void DestructorSkippable_;
diff --git a/src/google/protobuf/map_field_test.cc b/src/google/protobuf/map_field_test.cc
index ab75f8e..731d578 100644
--- a/src/google/protobuf/map_field_test.cc
+++ b/src/google/protobuf/map_field_test.cc
@@ -309,8 +309,8 @@
State state_;
};
-INSTANTIATE_TEST_CASE_P(MapFieldStateTestInstance, MapFieldStateTest,
- ::testing::Values(CLEAN, MAP_DIRTY, REPEATED_DIRTY));
+INSTANTIATE_TEST_SUITE_P(MapFieldStateTestInstance, MapFieldStateTest,
+ ::testing::Values(CLEAN, MAP_DIRTY, REPEATED_DIRTY));
TEST_P(MapFieldStateTest, GetMap) {
map_field_->GetMap();
diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h
index a8220b6..ddfedc8 100644
--- a/src/google/protobuf/map_type_handler.h
+++ b/src/google/protobuf/map_type_handler.h
@@ -31,7 +31,10 @@
#ifndef GOOGLE_PROTOBUF_TYPE_HANDLER_H__
#define GOOGLE_PROTOBUF_TYPE_HANDLER_H__
+#include <google/protobuf/parse_context.h>
+#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
+#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/wire_format_lite_inl.h>
#ifdef SWIG
@@ -165,6 +168,9 @@
static inline int GetCachedSize(const MapEntryAccessorType& value);
static inline bool Read(io::CodedInputStream* input,
MapEntryAccessorType* value);
+ static inline const char* Read(const char* ptr, ParseContext* ctx,
+ MapEntryAccessorType* value);
+
static inline void Write(int field, const MapEntryAccessorType& value,
io::CodedOutputStream* output);
static inline uint8* WriteToArray(int field,
@@ -221,6 +227,8 @@
static inline int GetCachedSize(const MapEntryAccessorType& value); \
static inline bool Read(io::CodedInputStream* input, \
MapEntryAccessorType* value); \
+ static inline const char* Read(const char* begin, ParseContext* ctx, \
+ MapEntryAccessorType* value); \
static inline void Write(int field, const MapEntryAccessorType& value, \
io::CodedOutputStream* output); \
static inline uint8* WriteToArray(int field, \
@@ -422,6 +430,96 @@
return WireFormatLite::ReadBytes(input, value);
}
+template <typename Type>
+const char* MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Read(
+ const char* ptr, ParseContext* ctx, MapEntryAccessorType* value) {
+ return ctx->ParseMessage(value, ptr);
+}
+
+template <typename Type>
+const char* MapTypeHandler<WireFormatLite::TYPE_STRING, Type>::Read(
+ const char* ptr, ParseContext* ctx, MapEntryAccessorType* value) {
+ int size = ReadSize(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ return ctx->ReadString(ptr, size, value);
+}
+
+template <typename Type>
+const char* MapTypeHandler<WireFormatLite::TYPE_BYTES, Type>::Read(
+ const char* ptr, ParseContext* ctx, MapEntryAccessorType* value) {
+ int size = ReadSize(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ return ctx->ReadString(ptr, size, value);
+}
+
+inline const char* ReadINT64(const char* ptr, int64* value) {
+ return ParseVarint64(ptr, reinterpret_cast<uint64*>(value));
+}
+inline const char* ReadUINT64(const char* ptr, uint64* value) {
+ return ParseVarint64(ptr, value);
+}
+inline const char* ReadINT32(const char* ptr, int32* value) {
+ uint64 tmp;
+ auto res = ParseVarint64(ptr, &tmp);
+ *value = static_cast<uint32>(tmp);
+ return res;
+}
+inline const char* ReadUINT32(const char* ptr, uint32* value) {
+ uint64 tmp;
+ auto res = ParseVarint64(ptr, &tmp);
+ *value = static_cast<uint32>(tmp);
+ return res;
+}
+inline const char* ReadSINT64(const char* ptr, int64* value) {
+ uint64 tmp;
+ auto res = ParseVarint64(ptr, &tmp);
+ *value = WireFormatLite::ZigZagDecode64(tmp);
+ return res;
+}
+inline const char* ReadSINT32(const char* ptr, int32* value) {
+ uint64 tmp;
+ auto res = ParseVarint64(ptr, &tmp);
+ *value = WireFormatLite::ZigZagDecode32(static_cast<uint32>(tmp));
+ return res;
+}
+template <typename E>
+inline const char* ReadENUM(const char* ptr, E* value) {
+ uint64 tmp;
+ auto res = ParseVarint64(ptr, &tmp);
+ *value = static_cast<E>(tmp);
+ return res;
+}
+inline const char* ReadBOOL(const char* ptr, bool* value) {
+ uint64 tmp;
+ auto res = ParseVarint64(ptr, &tmp);
+ *value = static_cast<bool>(tmp);
+ return res;
+}
+
+template <typename F>
+inline const char* ReadUnaligned(const char* ptr, F* value) {
+ *value = UnalignedLoad<F>(ptr);
+ return ptr + sizeof(F);
+}
+inline const char* ReadFLOAT(const char* ptr, float* value) {
+ return ReadUnaligned(ptr, value);
+}
+inline const char* ReadDOUBLE(const char* ptr, double* value) {
+ return ReadUnaligned(ptr, value);
+}
+inline const char* ReadFIXED64(const char* ptr, uint64* value) {
+ return ReadUnaligned(ptr, value);
+}
+inline const char* ReadFIXED32(const char* ptr, uint32* value) {
+ return ReadUnaligned(ptr, value);
+}
+inline const char* ReadSFIXED64(const char* ptr, int64* value) {
+ return ReadUnaligned(ptr, value);
+}
+inline const char* ReadSFIXED32(const char* ptr, int32* value) {
+ return ReadUnaligned(ptr, value);
+}
+
#define READ_METHOD(FieldType) \
template <typename Type> \
inline bool MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Read( \
@@ -429,6 +527,11 @@
return WireFormatLite::ReadPrimitive<TypeOnMemory, \
WireFormatLite::TYPE_##FieldType>( \
input, value); \
+ } \
+ template <typename Type> \
+ const char* MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Read( \
+ const char* begin, ParseContext* ctx, MapEntryAccessorType* value) { \
+ return Read##FieldType(begin, value); \
}
READ_METHOD(INT64)
diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc
index 3772594..d31f624 100644
--- a/src/google/protobuf/message.cc
+++ b/src/google/protobuf/message.cc
@@ -66,9 +66,6 @@
namespace google {
namespace protobuf {
-#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-using internal::ParseClosure;
-#endif
using internal::ReflectionOps;
using internal::WireFormat;
using internal::WireFormatLite;
@@ -269,14 +266,14 @@
return d->FindValueByNumber(val) != nullptr;
}
-ParseClosure GetPackedField(const FieldDescriptor* field, Message* msg,
- const Reflection* reflection,
- internal::ParseContext* ctx) {
+const char* ParsePackedField(const FieldDescriptor* field, Message* msg,
+ const Reflection* reflection, const char* ptr,
+ internal::ParseContext* ctx) {
switch (field->type()) {
#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, METHOD_NAME) \
case FieldDescriptor::TYPE_##TYPE: \
- return {internal::Packed##METHOD_NAME##Parser, \
- reflection->MutableRepeatedField<CPPTYPE>(msg, field)}
+ return internal::Packed##METHOD_NAME##Parser( \
+ reflection->MutableRepeatedField<CPPTYPE>(msg, field), ptr, ctx)
HANDLE_PACKED_TYPE(INT32, int32, Int32);
HANDLE_PACKED_TYPE(INT64, int64, Int64);
HANDLE_PACKED_TYPE(SINT32, int32, SInt32);
@@ -288,12 +285,11 @@
auto object =
internal::ReflectionAccessor::GetRepeatedEnum(reflection, field, msg);
if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
- return {internal::PackedEnumParser, object};
+ return internal::PackedEnumParser(object, ptr, ctx);
} else {
- ctx->extra_parse_data().SetEnumValidatorArg(
- ReflectiveValidator, field->enum_type(),
+ return internal::PackedEnumParserArg(
+ object, ptr, ctx, ReflectiveValidator, field->enum_type(),
reflection->MutableUnknownFields(msg), field->number());
- return {internal::PackedValidEnumParserArg, object};
}
}
HANDLE_PACKED_TYPE(FIXED32, uint32, Fixed32);
@@ -310,30 +306,40 @@
}
}
-ParseClosure GetLenDelim(int field_number, const FieldDescriptor* field,
- Message* msg, const Reflection* reflection,
- internal::ParseContext* ctx) {
+const char* ParseLenDelim(int field_number, const FieldDescriptor* field,
+ Message* msg, const Reflection* reflection,
+ const char* ptr, internal::ParseContext* ctx) {
if (WireFormat::WireTypeForFieldType(field->type()) !=
WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
GOOGLE_DCHECK(field->is_packable());
- return GetPackedField(field, msg, reflection, ctx);
+ return ParsePackedField(field, msg, reflection, ptr, ctx);
}
enum { kNone = 0, kVerify, kStrict } utf8_level = kNone;
- internal::ParseFunc string_parsers[] = {internal::StringParser,
- internal::StringParserUTF8Verify,
- internal::StringParserUTF8};
+ const char* field_name = nullptr;
+ auto parse_string = [ptr, ctx, &utf8_level, &field_name](string* s) {
+ switch (utf8_level) {
+ case kNone:
+ return internal::InlineGreedyStringParser(s, ptr, ctx);
+ case kVerify:
+ return internal::InlineGreedyStringParserUTF8Verify(s, ptr, ctx,
+ field_name);
+ case kStrict:
+ return internal::InlineGreedyStringParserUTF8(s, ptr, ctx, field_name);
+ }
+ };
switch (field->type()) {
- case FieldDescriptor::TYPE_STRING:
- if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3
- ) {
- ctx->extra_parse_data().SetFieldName(field->full_name().c_str());
+ case FieldDescriptor::TYPE_STRING: {
+ bool enforce_utf8 = true;
+ bool utf8_verification = true;
+ if (enforce_utf8 &&
+ field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
utf8_level = kStrict;
- } else if (
- true) {
- ctx->extra_parse_data().SetFieldName(field->full_name().c_str());
+ } else if (utf8_verification) {
utf8_level = kVerify;
}
+ field_name = field->full_name().c_str();
PROTOBUF_FALLTHROUGH_INTENDED;
+ }
case FieldDescriptor::TYPE_BYTES: {
if (field->is_repeated()) {
int index = reflection->FieldSize(*msg, field);
@@ -343,11 +349,11 @@
field->is_extension()) {
auto object = reflection->MutableRepeatedPtrField<string>(msg, field)
->Mutable(index);
- return {string_parsers[utf8_level], object};
+ return parse_string(object);
} else {
auto object = reflection->MutableRepeatedPtrField<string>(msg, field)
->Mutable(index);
- return {string_parsers[utf8_level], object};
+ return parse_string(object);
}
} else {
// Clear value and make sure it's set.
@@ -357,45 +363,42 @@
// HACK around inability to get mutable_string in reflection
string* object = &const_cast<string&>(
reflection->GetStringReference(*msg, field, nullptr));
- return {string_parsers[utf8_level], object};
+ return parse_string(object);
} else {
// HACK around inability to get mutable_string in reflection
string* object = &const_cast<string&>(
reflection->GetStringReference(*msg, field, nullptr));
- return {string_parsers[utf8_level], object};
+ return parse_string(object);
}
}
GOOGLE_LOG(FATAL) << "No other type than string supported";
}
case FieldDescriptor::TYPE_MESSAGE: {
Message* object;
- auto factory = ctx->extra_parse_data().factory;
if (field->is_repeated()) {
- object = reflection->AddMessage(msg, field, factory);
+ object = reflection->AddMessage(msg, field, ctx->data().factory);
} else {
- object = reflection->MutableMessage(msg, field, factory);
+ object = reflection->MutableMessage(msg, field, ctx->data().factory);
}
- return {object->_ParseFunc(), object};
+ return ctx->ParseMessage(object, ptr);
}
default:
GOOGLE_LOG(FATAL) << "Wrong type for length delim " << field->type();
}
- return {}; // Make compiler happy.
+ return nullptr; // Make compiler happy.
}
-ParseClosure GetGroup(int field_number, const FieldDescriptor* field,
- Message* msg, const Reflection* reflection) {
- Message* object;
+Message* GetGroup(int field_number, const FieldDescriptor* field, Message* msg,
+ const Reflection* reflection) {
if (field->is_repeated()) {
- object = reflection->AddMessage(msg, field, nullptr);
+ return reflection->AddMessage(msg, field, nullptr);
} else {
- object = reflection->MutableMessage(msg, field, nullptr);
+ return reflection->MutableMessage(msg, field, nullptr);
}
- return {object->_ParseFunc(), object};
}
-const char* Message::_InternalParse(const char* begin, const char* end,
- void* object, internal::ParseContext* ctx) {
+const char* Message::_InternalParse(const char* ptr,
+ internal::ParseContext* ctx) {
class ReflectiveFieldParser {
public:
ReflectiveFieldParser(Message* msg, internal::ParseContext* ctx)
@@ -403,19 +406,18 @@
void AddVarint(uint32 num, uint64 value) {
if (is_item_ && num == 2) {
- if (!ctx_->extra_parse_data().payload.empty()) {
+ if (!payload_.empty()) {
auto field = Field(value, 2);
if (field && field->message_type()) {
auto child = reflection_->MutableMessage(msg_, field);
// TODO(gerbens) signal error
- child->ParsePartialFromString(ctx_->extra_parse_data().payload);
+ child->ParsePartialFromString(payload_);
} else {
- MutableUnknown()->AddLengthDelimited(value)->swap(
- ctx_->extra_parse_data().payload);
+ MutableUnknown()->AddLengthDelimited(value)->swap(payload_);
}
return;
}
- ctx_->extra_parse_data().field_number = value;
+ type_id_ = value;
return;
}
auto field = Field(num, 0);
@@ -433,38 +435,41 @@
MutableUnknown()->AddFixed64(num, value);
}
}
- ParseClosure AddLengthDelimited(uint32 num, uint32) {
+ const char* ParseLengthDelimited(uint32 num, const char* ptr,
+ internal::ParseContext* ctx) {
if (is_item_ && num == 3) {
- int type_id = ctx_->extra_parse_data().field_number;
- if (type_id == 0) {
- return {internal::StringParser, &ctx_->extra_parse_data().payload};
+ if (type_id_ == 0) {
+ return InlineGreedyStringParser(&payload_, ptr, ctx);
}
- ctx_->extra_parse_data().field_number = 0;
- num = type_id;
+ num = type_id_;
+ type_id_ = 0;
}
auto field = Field(num, 2);
if (field) {
- return GetLenDelim(num, field, msg_, reflection_, ctx_);
+ return ParseLenDelim(num, field, msg_, reflection_, ptr, ctx);
} else {
- return {internal::StringParser,
- MutableUnknown()->AddLengthDelimited(num)};
+ return InlineGreedyStringParser(
+ MutableUnknown()->AddLengthDelimited(num), ptr, ctx);
}
}
- ParseClosure StartGroup(uint32 num) {
+ const char* ParseGroup(uint32 num, const char* ptr,
+ internal::ParseContext* ctx) {
if (!is_item_ && descriptor_->options().message_set_wire_format() &&
num == 1) {
- ctx_->extra_parse_data().payload.clear();
- ctx_->extra_parse_data().field_number = 0;
- return {ItemParser, msg_};
+ is_item_ = true;
+ ptr = ctx->ParseGroup(this, ptr, num * 8 + 3);
+ is_item_ = false;
+ type_id_ = 0;
+ return ptr;
}
auto field = Field(num, 3);
if (field) {
- return GetGroup(num, field, msg_, reflection_);
+ auto msg = GetGroup(num, field, msg_, reflection_);
+ return ctx->ParseGroup(msg, ptr, num * 8 + 3);
} else {
- return {internal::UnknownGroupParse, MutableUnknown()->AddGroup(num)};
+ return UnknownFieldParse(num * 8 + 3, MutableUnknown(), ptr, ctx);
}
}
- void EndGroup(uint32 num) {}
void AddFixed32(uint32 num, uint32 value) {
auto field = Field(num, 5);
if (field) {
@@ -474,6 +479,12 @@
}
}
+ const char* _InternalParse(const char* ptr, internal::ParseContext* ctx) {
+ // We're parsing the a MessageSetItem
+ GOOGLE_DCHECK(is_item_);
+ return internal::WireFormatParser(*this, ptr, ctx);
+ }
+
private:
Message* msg_;
const Descriptor* descriptor_;
@@ -481,6 +492,8 @@
internal::ParseContext* ctx_;
UnknownFieldSet* unknown_ = nullptr;
bool is_item_ = false;
+ uint32 type_id_ = 0;
+ string payload_;
ReflectiveFieldParser(Message* msg, internal::ParseContext* ctx,
bool is_item)
@@ -498,7 +511,7 @@
// If that failed, check if the field is an extension.
if (field == nullptr && descriptor_->IsExtensionNumber(num)) {
- const DescriptorPool* pool = ctx_->extra_parse_data().pool;
+ const DescriptorPool* pool = ctx_->data().pool;
if (pool == NULL) {
field = reflection_->FindKnownExtensionByNumber(num);
} else {
@@ -524,19 +537,10 @@
if (unknown_) return unknown_;
return unknown_ = reflection_->MutableUnknownFields(msg_);
}
-
- static const char* ItemParser(const char* begin, const char* end,
- void* object, internal::ParseContext* ctx) {
- auto msg = static_cast<Message*>(object);
- ReflectiveFieldParser field_parser(msg, ctx, true);
- return internal::WireFormatParser({ItemParser, object}, field_parser,
- begin, end, ctx);
- }
};
- ReflectiveFieldParser field_parser(static_cast<Message*>(object), ctx);
- return internal::WireFormatParser({_InternalParse, object}, field_parser,
- begin, end, ctx);
+ ReflectiveFieldParser field_parser(this, ctx);
+ return internal::WireFormatParser(field_parser, ptr, ctx);
}
#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index 02cca53..7fa17ed 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -321,20 +321,16 @@
void Clear() override;
bool IsInitialized() const override;
void CheckTypeAndMergeFrom(const MessageLite& other) override;
-#if !GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+ // Reflective parser
+ const char* _InternalParse(const char* ptr,
+ internal::ParseContext* ctx) override;
+#else
bool MergePartialFromCodedStream(io::CodedInputStream* input) override;
#endif
size_t ByteSizeLong() const override;
void SerializeWithCachedSizes(io::CodedOutputStream* output) const override;
-#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- internal::ParseFunc _ParseFunc() const override { return _InternalParse; }
-
- // Reflective parser
- static const char* _InternalParse(const char* begin, const char* end,
- void* object, internal::ParseContext* ctx);
-#endif
-
private:
// This is called only by the default implementation of ByteSize(), to
// update the cached size. If you override ByteSize(), you do not need
diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc
index 2f1261c..1df371a 100644
--- a/src/google/protobuf/message_lite.cc
+++ b/src/google/protobuf/message_lite.cc
@@ -44,8 +44,8 @@
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/arena.h>
-#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/generated_message_table_driven.h>
+#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/stubs/strutil.h>
@@ -117,92 +117,39 @@
namespace internal {
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-template <typename Next>
-bool ParseStream(const Next& next, MessageLite* msg) {
- internal::ParseContext ctx(io::CodedInputStream::GetDefaultRecursionLimit());
- EpsCopyParser<false> parser({msg->_ParseFunc(), msg}, &ctx);
- auto range = next();
- while (!range.empty()) {
- if (!parser.Parse(range)) return false;
- range = next();
- }
- return parser.Done();
-}
template <bool aliasing>
bool MergePartialFromImpl(StringPiece input, MessageLite* msg) {
- auto begin = input.data();
- int size = input.size();
- ParseContext ctx(io::CodedInputStream::GetDefaultRecursionLimit());
- internal::ParseClosure parser = {msg->_ParseFunc(), msg};
- // TODO(gerbens) fine tune
- constexpr int kThreshold = 48;
- static_assert(kThreshold >= ParseContext::kSlopBytes,
- "Requires enough room for at least kSlopBytes to be copied.");
- // TODO(gerbens) This could be left uninitialized and given an MSAN
- // annotation instead.
- char buffer[kThreshold + ParseContext::kSlopBytes] = {};
- if (size <= kThreshold) {
- std::memcpy(buffer, begin, size);
- if (aliasing) {
- ctx.extra_parse_data().aliasing =
- reinterpret_cast<std::uintptr_t>(begin) -
- reinterpret_cast<std::uintptr_t>(buffer);
- }
- return ctx.ParseExactRange(parser, buffer, buffer + size);
- }
- if (aliasing) {
- ctx.extra_parse_data().aliasing = ParseContext::ExtraParseData::kNoDelta;
- }
- size -= ParseContext::kSlopBytes;
- int overrun = 0;
- ctx.StartParse(parser);
- if (!ctx.ParseRange(StringPiece(begin, size), &overrun)) return false;
- begin += size;
- std::memcpy(buffer, begin, ParseContext::kSlopBytes);
- if (aliasing) {
- ctx.extra_parse_data().aliasing = reinterpret_cast<std::uintptr_t>(begin) -
- reinterpret_cast<std::uintptr_t>(buffer);
- }
- return ctx.ParseRange({buffer, ParseContext::kSlopBytes}, &overrun) &&
- ctx.ValidEnd(overrun);
-}
-
-StringPiece Next(BoundedZCIS* input) {
- const void* data;
- int size;
- if (input->limit == 0) return {};
- while (input->zcis->Next(&data, &size)) {
- if (size != 0) {
- input->limit -= size;
- if (input->limit < 0) {
- size += input->limit;
- input->zcis->BackUp(-input->limit);
- input->limit = 0;
- }
- return StringPiece(static_cast<const char*>(data), size);
- }
- }
- return {};
+ const char* ptr;
+ internal::ParseContext ctx(io::CodedInputStream::GetDefaultRecursionLimit(),
+ aliasing, &ptr, input);
+ return ctx.AtLegitimateEnd(msg->_InternalParse(ptr, &ctx));
}
template <bool aliasing>
bool MergePartialFromImpl(BoundedZCIS input, MessageLite* msg) {
- // TODO(gerbens) implement aliasing
- auto next = [&input]() { return Next(&input); };
- return ParseStream(next, msg) && input.limit == 0;
+ // TODO(gerbens) Circumvent CIS, to prevent slop region check overhead.
+ // Tricky case. If we limit ZeroCopyInputStream we need to make sure it's
+ // left precisely at the limit. However EpsCopyInputStream will always be
+ // 16 (kSlopBytes) bytes ahead of ZeroCopyInputStream, which means it's
+ // potentially a buffer ahead from which we can't rollback. Hence we must
+ // ensure we don't read more than the limit.
+ // TODO(gerbens) consider putting logic in EpsCopyInputStream to put an
+ // overall limit on the number of bytes it pulls from the underlying stream.
+ io::CodedInputStream cis(input.zcis);
+ cis.PushLimit(input.limit);
+ return msg->MergePartialFromCodedStream(&cis) && cis.BytesUntilLimit() == 0;
}
template <bool aliasing>
bool MergePartialFromImpl(io::ZeroCopyInputStream* input, MessageLite* msg) {
- // TODO(gerbens) implement aliasing
- BoundedZCIS bounded_zcis{input, INT_MAX};
- auto next = [&bounded_zcis]() { return Next(&bounded_zcis); };
- return ParseStream(next, msg) && bounded_zcis.limit > 0;
+ const char* ptr;
+ internal::ParseContext ctx(io::CodedInputStream::GetDefaultRecursionLimit(),
+ aliasing, &ptr, input);
+ return ctx.AtLegitimateEnd(msg->_InternalParse(ptr, &ctx));
}
-
-#else
+#else // !GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
inline bool InlineMergePartialEntireStream(io::CodedInputStream* cis,
MessageLite* message,
@@ -232,7 +179,7 @@
return InlineMergePartialEntireStream(&decoder, msg, aliasing);
}
-#endif
+#endif // !GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
template bool MergePartialFromImpl<false>(StringPiece input,
MessageLite* msg);
@@ -256,43 +203,46 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-bool MessageLite::MergePartialFromCodedStream(io::CodedInputStream* input) {
- // MergePartialFromCodedStream must leave input in "exactly" the same state
- // as the old implementation. At least when the parse is successful. For
- // MergePartialFromCodedStream a successful parse can also occur by ending
- // on a zero tag or an end-group tag. In these cases input is left precisely
- // past the terminating tag and last_tag_ is set to the terminating tags
- // value. If the parse ended on a limit (either a pushed limit or end of the
- // ZeroCopyInputStream) legitimate_end_ is set to true.
- int size = 0;
- auto next = [input, &size]() {
- const void* ptr;
- input->Skip(size); // skip previous buffer
- if (!input->GetDirectBufferPointer(&ptr, &size)) return StringPiece{};
- return StringPiece(static_cast<const char*>(ptr), size);
- };
- internal::ParseContext ctx(input->RecursionBudget());
- ctx.extra_parse_data().pool = input->GetExtensionPool();
- ctx.extra_parse_data().factory = input->GetExtensionFactory();
- internal::EpsCopyParser<true> parser({_ParseFunc(), this}, &ctx);
- auto range = next();
- while (!range.empty()) {
- if (!parser.Parse(range)) {
- if (!ctx.EndedOnTag()) return false;
- // Parse ended on a zero or end-group tag, leave the stream in the
- // appropriate state. Note we only skip forward, due to using
- // ensure_non_negative_skip being set to true in parser.
- input->Skip(parser.Skip());
- input->SetLastTag(ctx.LastTag());
- return true;
- }
- range = next();
+class ZeroCopyCodedInputStream : public io::ZeroCopyInputStream {
+ public:
+ ZeroCopyCodedInputStream(io::CodedInputStream* cis) : cis_(cis) {}
+ bool Next(const void** data, int* size) final {
+ if (!cis_->GetDirectBufferPointer(data, size)) return false;
+ cis_->Skip(*size);
+ return true;
}
- if (!parser.Done()) return false;
- input->SetConsumed();
+ void BackUp(int count) final { cis_->Advance(-count); }
+ bool Skip(int count) final { return cis_->Skip(count); }
+ int64 ByteCount() const final { return 0; }
+
+ bool aliasing_enabled() { return cis_->aliasing_enabled_; }
+
+ private:
+ io::CodedInputStream* cis_;
+};
+
+bool MessageLite::MergePartialFromCodedStream(io::CodedInputStream* input) {
+ ZeroCopyCodedInputStream zcis(input);
+ const char* ptr;
+ internal::ParseContext ctx(input->RecursionBudget(), zcis.aliasing_enabled(),
+ &ptr, &zcis);
+ // MergePartialFromCodedStream allows terminating the wireformat by 0 or
+ // end-group tag. Leaving it up to the caller to verify correct ending by
+ // calling LastTagWas on input. We need to maintain this behavior.
+ ctx.TrackCorrectEnding();
+ ctx.data().pool = input->GetExtensionPool();
+ ctx.data().factory = input->GetExtensionFactory();
+ ptr = _InternalParse(ptr, &ctx);
+ if (!ptr) return false;
+ ctx.BackUp(ptr);
+ if (ctx.LastTagMinus1() != 0) {
+ input->SetLastTag(ctx.LastTagMinus1() + 1);
+ return true;
+ }
+ if (ctx.AtLimit(ptr)) input->SetConsumed();
return true;
}
-#endif
+#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool MessageLite::MergeFromCodedStream(io::CodedInputStream* input) {
return MergePartialFromCodedStream(input) && IsInitializedWithErrors();
diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h
index 1e07141..61c2d2a 100644
--- a/src/google/protobuf/message_lite.h
+++ b/src/google/protobuf/message_lite.h
@@ -41,6 +41,7 @@
#include <climits>
#include <string>
+
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/arena.h>
@@ -71,12 +72,8 @@
} // namespace io
namespace internal {
-#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
// See parse_context.h for explanation
class ParseContext;
-typedef const char* (*ParseFunc)(const char* ptr, const char* end, void* object,
- ParseContext* ctx);
-#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
class RepeatedPtrFieldBase;
class WireFormatLite;
@@ -401,9 +398,8 @@
virtual int GetCachedSize() const = 0;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- virtual internal::ParseFunc _ParseFunc() const {
- GOOGLE_LOG(FATAL) << "Type " << GetTypeName()
- << " doesn't implement _InternalParse";
+ virtual const char* _InternalParse(const char* ptr,
+ internal::ParseContext* ctx) {
return nullptr;
}
#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
@@ -496,7 +492,6 @@
extern template bool MergePartialFromImpl<true>(BoundedZCIS input,
MessageLite* msg);
-
template <typename T>
struct SourceWrapper;
@@ -511,8 +506,8 @@
bool MessageLite::ParseFrom(const T& input) {
if (flags & kParse) Clear();
constexpr bool alias = flags & kMergeWithAliasing;
- return internal::MergePartialFromImpl<alias>(input, this) &&
- ((flags & kMergePartial) || IsInitializedWithErrors());
+ bool res = internal::MergePartialFromImpl<alias>(input, this);
+ return res && ((flags & kMergePartial) || IsInitializedWithErrors());
}
} // namespace protobuf
diff --git a/src/google/protobuf/parse_context.cc b/src/google/protobuf/parse_context.cc
index a522966..2954105 100644
--- a/src/google/protobuf/parse_context.cc
+++ b/src/google/protobuf/parse_context.cc
@@ -32,6 +32,7 @@
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/wire_format_lite.h>
@@ -43,51 +44,18 @@
namespace protobuf {
namespace internal {
-bool ParseContext::ParseEndsInSlopRegion(const char* begin, int overrun) const {
+namespace {
+
+// Only call if at start of tag.
+bool ParseEndsInSlopRegion(const char* begin, int overrun, int d) {
+ constexpr int kSlopBytes = EpsCopyInputStream::kSlopBytes;
GOOGLE_DCHECK(overrun >= 0);
GOOGLE_DCHECK(overrun <= kSlopBytes);
auto ptr = begin + overrun;
auto end = begin + kSlopBytes;
- int n = end - ptr;
- if (n == 0) return false;
- // If limit_ != -1 then the parser will continue to parse at least limit_
- // bytes (or more if on the stack there are further limits)
- int d = depth_;
- if (limit_ != -1) {
- GOOGLE_DCHECK(d < start_depth_); // Top-level never has a limit.
- // rewind the stack until all limits disappear.
- int limit = limit_;
- if (limit >= n) return false;
- while (d < start_depth_) {
- int delta = stack_[d++].delta_or_group_num;
- if (delta == -1) {
- // We found the first limit that was pushed. We should inspect from
- // this point on.
- ptr += limit;
- break;
- } else if (delta >= 0) {
- // We reached end of a length delimited subfield. Adjust limit
- limit += delta;
- if (limit >= n) return false;
- } else {
- // It's a group we assume the format is correct and this group
- // is properly ended before the limit is reached.
- }
- }
- }
- d = start_depth_ - d; // We just keep track of the depth from start.
- // We verify that a generic parse of the buffer won't, validly, end the parse
- // before end, due to ending the top-level on a 0 or end-group tag.
- // IMPORTANT NOTE: we return false in failure cases. This is
- // important because we could fail due to overrunning the buffer and read
- // garbage data beyond the buffer (valid reads just left over garbage). So
- // failure doesn't imply the parse will fail. So if this loops fails while
- // the real parse would succeed it means the real parse will read beyond the
- // boundary. If the real parse fails we can't reasonably continue the stream
- // any way so we make no attempt to leave the stream at a well specified pos.
while (ptr < end) {
uint32 tag;
- ptr = io::Parse32(ptr, &tag);
+ ptr = ReadTag(ptr, &tag);
if (ptr == nullptr || ptr > end) return false;
// ending on 0 tag is allowed and is the major reason for the necessity of
// this function.
@@ -95,7 +63,7 @@
switch (tag & 7) {
case 0: { // Varint
uint64 val;
- ptr = io::Parse64(ptr, &val);
+ ptr = ParseVarint64(ptr, &val);
if (ptr == nullptr) return false;
break;
}
@@ -104,9 +72,8 @@
break;
}
case 2: { // len delim
- uint32 size;
- ptr = io::Parse32(ptr, &size);
- if (ptr == nullptr) return false;
+ int32 size = ReadSize(&ptr);
+ if (ptr == nullptr || size > end - ptr) return false;
ptr += size;
break;
}
@@ -129,312 +96,151 @@
return false;
}
-void ParseContext::SwitchStack() {
- stack_ = new State[start_depth_];
- std::memcpy(stack_ + inlined_depth_, inline_stack_, sizeof(inline_stack_));
- inlined_depth_ = -1; // Special value to indicate stack_ needs to be deleted
+} // namespace
+
+const char* EpsCopyInputStream::Next(int overrun, int d) {
+ if (next_chunk_ == nullptr) return nullptr; // We've reached end of stream.
+ if (next_chunk_ != buffer_) {
+ GOOGLE_DCHECK(size_ > kSlopBytes);
+ // The chunk is large enough to be used directly
+ buffer_end_ = next_chunk_ + size_ - kSlopBytes;
+ auto res = next_chunk_;
+ next_chunk_ = buffer_;
+ if (aliasing_ == kOnPatch) aliasing_ = kNoDelta;
+ return res;
+ }
+ // Move the slop bytes of previous buffer to start of the patch buffer.
+ // Note we must use memmove because the previous buffer could be part of
+ // buffer_.
+ std::memmove(buffer_, buffer_end_, kSlopBytes);
+ if (zcis_ && (d < 0 || !ParseEndsInSlopRegion(buffer_, overrun, d))) {
+ const void* data;
+ // ZeroCopyInputStream indicates Next may return 0 size buffers. Hence
+ // we loop.
+ while (zcis_->Next(&data, &size_)) {
+ if (size_ > kSlopBytes) {
+ // We got a large chunk
+ std::memcpy(buffer_ + kSlopBytes, data, kSlopBytes);
+ next_chunk_ = static_cast<const char*>(data);
+ buffer_end_ = buffer_ + kSlopBytes;
+ if (aliasing_ >= kNoDelta) aliasing_ = kOnPatch;
+ return buffer_;
+ } else if (size_ > 0) {
+ std::memcpy(buffer_ + kSlopBytes, data, size_);
+ next_chunk_ = buffer_;
+ buffer_end_ = buffer_ + size_;
+ if (aliasing_ >= kNoDelta) aliasing_ = kOnPatch;
+ return buffer_;
+ }
+ GOOGLE_DCHECK(size_ == 0) << size_;
+ }
+ }
+ // End of stream or array
+ if (aliasing_ == kNoDelta) {
+ // If there is no more block and aliasing is true, the previous block
+ // is still valid and we can alias. We have users relying on string_view's
+ // obtained from protos to outlive the proto, when the parse was from an
+ // array. This guarantees string_view's are always aliased if parsed from
+ // an array.
+ aliasing_ = reinterpret_cast<std::uintptr_t>(buffer_end_) -
+ reinterpret_cast<std::uintptr_t>(buffer_);
+ }
+ next_chunk_ = nullptr;
+ buffer_end_ = buffer_ + kSlopBytes;
+ size_ = 0;
+ return buffer_;
}
-std::pair<bool, int> ParseContext::ParseRangeWithLimit(const char* begin,
- const char* end) {
- auto ptr = begin;
+std::pair<const char*, bool> EpsCopyInputStream::DoneFallback(const char* ptr,
+ int d) {
+ GOOGLE_DCHECK(ptr >= limit_end_);
+ int overrun = ptr - buffer_end_;
+ GOOGLE_DCHECK(overrun <= kSlopBytes); // Guaranteed by parse loop.
+ GOOGLE_DCHECK(overrun != limit_);
+ // We either exceeded the limit (parse error) or we need to get new data.
+ // Did we exceed the limit? Is so parse error.
+ if (PROTOBUF_PREDICT_FALSE(overrun > limit_)) {
+ return {nullptr, true};
+ }
+ GOOGLE_DCHECK(overrun <= limit_); // Follows from above
+ // At this point we know the following assertion holds.
+ GOOGLE_DCHECK(limit_ > 0);
+ GOOGLE_DCHECK(limit_end_ == buffer_end_); // because limit_ > 0
do {
- GOOGLE_DCHECK(ptr < end);
- const char* limited_end;
- if (limit_ == -1) {
- limited_end = end;
- } else {
- GOOGLE_DCHECK(limit_ > 0);
- limited_end = ptr + std::min(static_cast<int32>(end - ptr), limit_);
- limit_ -= limited_end - ptr;
- }
- // Parse the range [ptr, limited_end). The only case (except for error) that
- // the parser can return prematurely (before limited_end) is on encountering
- // an end-group. If this is the case we continue parsing the range with
- // the parent parser.
- do {
- GOOGLE_DCHECK(ptr < limited_end);
- ptr = parser_(ptr, limited_end, this);
- if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) {
- // Clear last_tag_minus_1_ so that the hard error encountered is not
- // mistaken for ending on a tag.
- last_tag_minus_1_ = 0;
- return {};
- }
- if (!EndedOnTag()) {
- // The parser ended still parsing the initial message. This can only
- // happen because it crossed the end.
- GOOGLE_DCHECK(ptr >= limited_end);
- break;
- }
- // Child parser terminated on an end-group / 0 tag.
- GOOGLE_DCHECK(depth_ <= start_depth_);
- if (depth_ == start_depth_) {
- // The parse was already at the top-level and there is no parent.
- // This can happen due to encountering 0 or due to this parser being
- // called for parsing a sub-group message in custom parsing code.
- return {false, static_cast<int>(ptr - end)};
- }
- auto state = Pop();
- // Verify the ending tag is correct and continue parsing the range with
- // the parent parser.
- uint32 group_number = last_tag_minus_1_ >> 3;
- // We need to clear last_tag_minus_1_, either for the next iteration
- // or if the if statement below returns.
- last_tag_minus_1_ = 0;
- if (state.delta_or_group_num != ~group_number) return {};
- parser_ = state.parser; // Load parent parser
- } while (ptr < limited_end);
- int overrun = ptr - limited_end;
+ // We are past the end of buffer_end_, in the slop region.
GOOGLE_DCHECK(overrun >= 0);
- GOOGLE_DCHECK(overrun <= kSlopBytes); // wireformat guarantees this limit
- if (limit_ != -1) {
- limit_ -= overrun; // Adjust limit relative to new position.
- if (limit_ < 0) return {}; // We overrun the limit
- while (limit_ == 0) {
- // We are at an actual ending of a length delimited field.
- // The top level has no limit (ie. limit_ == -1) so we can assert
- // that the stack is non-empty.
- GOOGLE_DCHECK(depth_ < start_depth_);
- // else continue parsing the parent message.
- auto state = Pop();
- parser_ = state.parser;
- limit_ = state.delta_or_group_num;
- // No group ending is possible here. Any group on the stack still
- // needs to read its end-group tag and can't be on a limit_ == 0.
- if (limit_ < -1) return {};
+ auto p = Next(overrun, d);
+ if (p == nullptr) {
+ // We are at the end of the stream
+ if (PROTOBUF_PREDICT_FALSE(overrun != 0)) {
+ return {nullptr, true};
}
+ GOOGLE_DCHECK(limit_ > 0);
+ limit_end_ = buffer_end_;
+ return {ptr, true};
}
- } while (ptr < end);
- return {true, static_cast<int>(ptr - end)};
+ limit_ -= buffer_end_ - p; // Adjust limit_ relative to new anchor
+ ptr = p + overrun;
+ overrun = ptr - buffer_end_;
+ } while (overrun >= 0);
+ limit_end_ = buffer_end_ + std::min(0, limit_);
+ return {ptr, false};
}
-const char* StringParser(const char* begin, const char* end, void* object,
- ParseContext*) {
- auto str = static_cast<string*>(object);
- str->append(begin, end - begin);
- return end;
+const char* EpsCopyInputStream::SkipFallback(const char* ptr, int size) {
+ return AppendSize(ptr, size, [](const char* p, int s) {});
}
-// Defined in wire_format_lite.cc
-void PrintUTF8ErrorLog(const char* field_name, const char* operation_str,
- bool emit_stacktrace);
-
-bool VerifyUTF8(StringPiece str, ParseContext* ctx) {
- if (!IsStructurallyValidUTF8(str)) {
- PrintUTF8ErrorLog(ctx->extra_parse_data().FieldName(), "parsing", false);
- return false;
- }
- return true;
+const char* EpsCopyInputStream::ReadStringFallback(const char* ptr, int size,
+ string* s) {
+ s->clear();
+ return AppendStringFallback(ptr, size, s);
}
-const char* StringParserUTF8(const char* begin, const char* end, void* object,
- ParseContext* ctx) {
- StringParser(begin, end, object, ctx);
- if (ctx->AtLimit()) {
- auto str = static_cast<string*>(object);
- GOOGLE_PROTOBUF_PARSER_ASSERT(VerifyUTF8(*str, ctx));
- }
- return end;
-}
-
-const char* StringParserUTF8Verify(const char* begin, const char* end,
- void* object, ParseContext* ctx) {
- StringParser(begin, end, object, ctx);
-#ifndef NDEBUG
- if (ctx->AtLimit()) {
- auto str = static_cast<string*>(object);
- VerifyUTF8(*str, ctx);
- }
-#endif
- return end;
+const char* EpsCopyInputStream::AppendStringFallback(const char* ptr, int size,
+ string* str) {
+ return AppendSize(ptr, size,
+ [str](const char* p, int s) { str->append(p, s); });
}
-const char* GreedyStringParser(const char* begin, const char* end, void* object,
- ParseContext* ctx) {
- auto str = static_cast<string*>(object);
- auto limit = ctx->CurrentLimit();
- GOOGLE_DCHECK(limit != -1); // Always length delimited
- end += std::min<int>(limit, ParseContext::kSlopBytes);
- str->append(begin, end - begin);
- return end;
+template <typename Tag, typename T>
+const char* EpsCopyInputStream::ReadRepeatedFixed(const char* ptr,
+ Tag expected_tag,
+ RepeatedField<T>* out) {
+ do {
+ out->Add(UnalignedLoad<T>(ptr));
+ ptr += sizeof(T);
+ if (PROTOBUF_PREDICT_FALSE(ptr >= limit_end_)) return ptr;
+ } while (UnalignedLoad<Tag>(ptr) == expected_tag&& ptr += sizeof(Tag));
+ return ptr;
}
-const char* GreedyStringParserUTF8(const char* begin, const char* end, void* object,
- ParseContext* ctx) {
- auto limit = ctx->CurrentLimit();
- GOOGLE_DCHECK(limit != -1); // Always length delimited
- bool at_end;
- if (limit <= ParseContext::kSlopBytes) {
- end += limit;
- at_end = true;
- } else {
- end += ParseContext::kSlopBytes;
- at_end =false;
- }
- auto str = static_cast<string*>(object);
- str->append(begin, end - begin);
- if (at_end) {
- GOOGLE_PROTOBUF_PARSER_ASSERT(VerifyUTF8(*str, ctx));
- }
- return end;
-}
-
-const char* GreedyStringParserUTF8Verify(const char* begin, const char* end, void* object,
- ParseContext* ctx) {
- auto limit = ctx->CurrentLimit();
- GOOGLE_DCHECK(limit != -1); // Always length delimited
- bool at_end;
- if (limit <= ParseContext::kSlopBytes) {
- end += limit;
- at_end = true;
- } else {
- end += ParseContext::kSlopBytes;
- at_end =false;
- }
- auto str = static_cast<string*>(object);
- str->append(begin, end - begin);
- if (at_end) {
-#ifndef NDEBUG
- VerifyUTF8(*str, ctx);
-#endif
- }
- return end;
-}
-
-template <typename T, bool sign>
-const char* VarintParser(const char* begin, const char* end, void* object,
- ParseContext*) {
- auto repeated_field = static_cast<RepeatedField<T>*>(object);
- auto ptr = begin;
- while (ptr < end) {
- uint64 varint;
- ptr = io::Parse64(ptr, &varint);
- if (!ptr) return nullptr;
- T val;
- if (sign) {
- if (sizeof(T) == 8) {
- val = WireFormatLite::ZigZagDecode64(varint);
- } else {
- val = WireFormatLite::ZigZagDecode32(varint);
- }
+const char* EpsCopyInputStream::InitFrom(io::ZeroCopyInputStream* zcis) {
+ zcis_ = zcis;
+ const void* data;
+ int size;
+ if (zcis->Next(&data, &size)) {
+ if (size > kSlopBytes) {
+ auto ptr = static_cast<const char*>(data);
+ limit_ -= size - kSlopBytes;
+ limit_end_ = buffer_end_ = ptr + size - kSlopBytes;
+ if (aliasing_ == kOnPatch) aliasing_ = kNoDelta;
+ return ptr;
} else {
- val = varint;
+ auto ptr = buffer_ + 2 * kSlopBytes - size;
+ std::memcpy(ptr, data, size);
+ return ptr;
}
- repeated_field->Add(val);
}
- return ptr;
+ next_chunk_ = nullptr;
+ size_ = 0;
+ limit_ = 0;
+ limit_end_ = buffer_end_ = buffer_;
+ return buffer_;
}
-template <typename T>
-const char* FixedParser(const char* begin, const char* end, void* object,
- ParseContext*) {
- auto repeated_field = static_cast<RepeatedField<T>*>(object);
- int num = (end - begin + sizeof(T) - 1) / sizeof(T);
-
- const int old_entries = repeated_field->size();
- repeated_field->Reserve(old_entries + num);
- std::memcpy(repeated_field->AddNAlreadyReserved(num), begin, num * sizeof(T));
- return begin + num * sizeof(T);
-}
-
-const char* PackedInt32Parser(const char* begin, const char* end, void* object,
- ParseContext* ctx) {
- return VarintParser<int32, false>(begin, end, object, ctx);
-}
-const char* PackedUInt32Parser(const char* begin, const char* end, void* object,
- ParseContext* ctx) {
- return VarintParser<uint32, false>(begin, end, object, ctx);
-}
-const char* PackedInt64Parser(const char* begin, const char* end, void* object,
- ParseContext* ctx) {
- return VarintParser<int64, false>(begin, end, object, ctx);
-}
-const char* PackedUInt64Parser(const char* begin, const char* end, void* object,
- ParseContext* ctx) {
- return VarintParser<uint64, false>(begin, end, object, ctx);
-}
-const char* PackedSInt32Parser(const char* begin, const char* end, void* object,
- ParseContext* ctx) {
- return VarintParser<int32, true>(begin, end, object, ctx);
-}
-const char* PackedSInt64Parser(const char* begin, const char* end, void* object,
- ParseContext* ctx) {
- return VarintParser<int64, true>(begin, end, object, ctx);
-}
-
-const char* PackedEnumParser(const char* begin, const char* end, void* object,
- ParseContext* ctx) {
- return VarintParser<int, false>(begin, end, object, ctx);
-}
-
-const char* PackedValidEnumParserLite(const char* begin, const char* end,
- void* object, ParseContext* ctx) {
- auto repeated_field = static_cast<RepeatedField<int>*>(object);
- auto ptr = begin;
- while (ptr < end) {
- uint64 varint;
- ptr = io::Parse64(ptr, &varint);
- if (!ptr) return nullptr;
- int val = varint;
- if (ctx->extra_parse_data().ValidateEnum<string>(val))
- repeated_field->Add(val);
- }
- return ptr;
-}
-
-const char* PackedValidEnumParserLiteArg(const char* begin, const char* end,
- void* object, ParseContext* ctx) {
- auto repeated_field = static_cast<RepeatedField<int>*>(object);
- auto ptr = begin;
- while (ptr < end) {
- uint64 varint;
- ptr = io::Parse64(ptr, &varint);
- if (!ptr) return nullptr;
- int val = varint;
- if (ctx->extra_parse_data().ValidateEnumArg<string>(val))
- repeated_field->Add(val);
- }
- return ptr;
-}
-
-const char* PackedBoolParser(const char* begin, const char* end, void* object,
- ParseContext* ctx) {
- return VarintParser<bool, false>(begin, end, object, ctx);
-}
-
-const char* PackedFixed32Parser(const char* begin, const char* end,
- void* object, ParseContext* ctx) {
- return FixedParser<uint32>(begin, end, object, ctx);
-}
-const char* PackedSFixed32Parser(const char* begin, const char* end,
- void* object, ParseContext* ctx) {
- return FixedParser<int32>(begin, end, object, ctx);
-}
-const char* PackedFixed64Parser(const char* begin, const char* end,
- void* object, ParseContext* ctx) {
- return FixedParser<uint64>(begin, end, object, ctx);
-}
-const char* PackedSFixed64Parser(const char* begin, const char* end,
- void* object, ParseContext* ctx) {
- return FixedParser<int64>(begin, end, object, ctx);
-}
-const char* PackedFloatParser(const char* begin, const char* end, void* object,
- ParseContext* ctx) {
- return FixedParser<float>(begin, end, object, ctx);
-}
-const char* PackedDoubleParser(const char* begin, const char* end, void* object,
- ParseContext* ctx) {
- return FixedParser<double>(begin, end, object, ctx);
-}
-
-const char* NullParser(const char* begin, const char* end, void* object,
- ParseContext* ctx) {
- return end;
-}
-
-void WriteVarint(uint64 val, string* s) {
+inline void WriteVarint(uint64 val, string* s) {
while (val >= 128) {
uint8 c = val | 0x80;
s->push_back(c);
@@ -454,6 +260,255 @@
s->append(val.data(), val.size());
}
+std::pair<const char*, uint32> Parse32Fallback(const char* p, uint32 res) {
+ uint32 extra = 128 + 128 * 128;
+ for (std::uint32_t i = 0; i < 3; i++) {
+ std::uint32_t byte = static_cast<uint8>(p[i]);
+ res += byte << (7 * (i + 2));
+ if (PROTOBUF_PREDICT_TRUE(byte < 128)) {
+ return {p + i + 1, res - extra};
+ }
+ extra += (1ull << (7 * (i + 3)));
+ }
+ return {nullptr, 0};
+}
+
+std::pair<const char*, uint32> FinishReadTag1Fallback(const char* p, uint32 res) {
+ uint32 extra = 128;
+ for (std::uint32_t i = 0; i < 4; i++) {
+ std::uint32_t byte = static_cast<uint8>(p[i]);
+ res += byte << (7 * (i + 1));
+ if (PROTOBUF_PREDICT_TRUE(byte < 128)) {
+ return {p + i + 1, res - extra};
+ }
+ extra += (1ull << (7 * (i + 2)));
+ }
+ return {nullptr, 0};
+}
+
+std::pair<const char*, uint32> FinishReadTag2Fallback(const char* p, uint32 res) {
+ uint32 extra = 128 * 128;
+ for (std::uint32_t i = 0; i < 3; i++) {
+ std::uint32_t byte = static_cast<uint8>(p[i]);
+ res += byte << (7 * (i + 2));
+ if (PROTOBUF_PREDICT_TRUE(byte < 128)) {
+ return {p + i + 1, res - extra};
+ }
+ extra += (1ull << (7 * (i + 3)));
+ }
+ return {nullptr, 0};
+}
+
+std::pair<const char*, uint64> ParseVarint64Fallback(const char* p, uint64 res) {
+ res >>= 1;
+ for (std::uint32_t i = 0; i < 4; i++) {
+ std::uint32_t tmp;
+ auto pnew = DecodeTwoBytes(p + 2 * i, &tmp);
+ res += (static_cast<std::uint64_t>(tmp) - 2) << (14 * (i + 1) - 1);
+ if (PROTOBUF_PREDICT_TRUE(std::int16_t(tmp) >= 0)) {
+ return {pnew, res};
+ }
+ }
+ return {nullptr, res};
+}
+
+std::pair<const char*, int32> ReadSizeFallback(const char* p, uint32 first) {
+ uint32 tmp;
+ auto res = VarintParse<4>(p + 1, &tmp);
+ if (tmp >= (1 << 24) - ParseContext::kSlopBytes) return {nullptr, 0};
+ return {res, (tmp << 7) + first - 0x80};
+}
+
+const char* StringParser(const char* begin, const char* end, void* object,
+ ParseContext*) {
+ auto str = static_cast<string*>(object);
+ str->append(begin, end - begin);
+ return end;
+}
+
+// Defined in wire_format_lite.cc
+void PrintUTF8ErrorLog(const char* field_name, const char* operation_str,
+ bool emit_stacktrace);
+
+bool VerifyUTF8(StringPiece str, const char* field_name) {
+ if (!IsStructurallyValidUTF8(str)) {
+ PrintUTF8ErrorLog(field_name, "parsing", false);
+ return false;
+ }
+ return true;
+}
+
+const char* InlineGreedyStringParserUTF8(string* s, const char* ptr,
+ ParseContext* ctx,
+ const char* field_name) {
+ auto p = InlineGreedyStringParser(s, ptr, ctx);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(VerifyUTF8(*s, field_name));
+ return p;
+}
+
+const char* InlineGreedyStringParserUTF8Verify(string* s, const char* ptr,
+ ParseContext* ctx,
+ const char* field_name) {
+ auto p = InlineGreedyStringParser(s, ptr, ctx);
+#ifndef NDEBUG
+ VerifyUTF8(*s, field_name);
+#endif // !NDEBUG
+ return p;
+}
+
+
+template <typename T, bool sign>
+const char* VarintParser(void* object, const char* ptr, ParseContext* ctx) {
+ int size = ReadSize(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ auto old = ctx->PushLimit(ptr, size);
+ if (old < 0) return nullptr;
+ auto repeated_field = static_cast<RepeatedField<T>*>(object);
+ while (!ctx->DoneNoSlopCheck(&ptr)) {
+ uint64 varint;
+ ptr = ParseVarint64(ptr, &varint);
+ if (!ptr) return nullptr;
+ T val;
+ if (sign) {
+ if (sizeof(T) == 8) {
+ val = WireFormatLite::ZigZagDecode64(varint);
+ } else {
+ val = WireFormatLite::ZigZagDecode32(varint);
+ }
+ } else {
+ val = varint;
+ }
+ repeated_field->Add(val);
+ }
+ ctx->PopLimit(old);
+ return ptr;
+}
+
+template <typename T>
+const char* FixedParser(void* object, const char* ptr, ParseContext* ctx) {
+ int size = ReadSize(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ auto old = ctx->PushLimit(ptr, size);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(old >= 0);
+ auto repeated_field = static_cast<RepeatedField<T>*>(object);
+ while (!ctx->DoneNoSlopCheck(&ptr)) {
+ int num = (ctx->ConsecutiveBytes(ptr) + sizeof(T) - 1) / sizeof(T);
+
+ const int old_entries = repeated_field->size();
+ repeated_field->Reserve(old_entries + num);
+ std::memcpy(repeated_field->AddNAlreadyReserved(num), ptr, num * sizeof(T));
+ ptr = ptr + num * sizeof(T);
+ }
+ ctx->PopLimit(old);
+ return ptr;
+}
+
+const char* PackedInt32Parser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return VarintParser<int32, false>(object, ptr, ctx);
+}
+const char* PackedUInt32Parser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return VarintParser<uint32, false>(object, ptr, ctx);
+}
+const char* PackedInt64Parser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return VarintParser<int64, false>(object, ptr, ctx);
+}
+const char* PackedUInt64Parser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return VarintParser<uint64, false>(object, ptr, ctx);
+}
+const char* PackedSInt32Parser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return VarintParser<int32, true>(object, ptr, ctx);
+}
+const char* PackedSInt64Parser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return VarintParser<int64, true>(object, ptr, ctx);
+}
+
+const char* PackedEnumParser(void* object, const char* ptr, ParseContext* ctx) {
+ return VarintParser<int, false>(object, ptr, ctx);
+}
+
+const char* PackedEnumParser(void* object, const char* ptr, ParseContext* ctx,
+ bool (*is_valid)(int), string* unknown,
+ int field_num) {
+ int size = ReadSize(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ auto old = ctx->PushLimit(ptr, size);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(old >= 0);
+ auto repeated_field = static_cast<RepeatedField<int>*>(object);
+ while (!ctx->DoneNoSlopCheck(&ptr)) {
+ uint64 varint;
+ ptr = ParseVarint64(ptr, &varint);
+ if (!ptr) return nullptr;
+ int val = varint;
+ if (is_valid(val)) {
+ repeated_field->Add(val);
+ } else {
+ WriteVarint(field_num, val, unknown);
+ }
+ }
+ ctx->PopLimit(old);
+ return ptr;
+}
+
+const char* PackedEnumParserArg(void* object, const char* ptr,
+ ParseContext* ctx,
+ bool (*is_valid)(const void*, int),
+ const void* data, string* unknown,
+ int field_num) {
+ int size = ReadSize(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ auto old = ctx->PushLimit(ptr, size);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(old >= 0);
+ auto repeated_field = static_cast<RepeatedField<int>*>(object);
+ while (!ctx->DoneNoSlopCheck(&ptr)) {
+ uint64 varint;
+ ptr = ParseVarint64(ptr, &varint);
+ if (!ptr) return nullptr;
+ int val = varint;
+ if (is_valid(data, val)) {
+ repeated_field->Add(val);
+ } else {
+ WriteVarint(field_num, val, unknown);
+ }
+ }
+ ctx->PopLimit(old);
+ return ptr;
+}
+
+const char* PackedBoolParser(void* object, const char* ptr, ParseContext* ctx) {
+ return VarintParser<bool, false>(object, ptr, ctx);
+}
+
+const char* PackedFixed32Parser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return FixedParser<uint32>(object, ptr, ctx);
+}
+const char* PackedSFixed32Parser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return FixedParser<int32>(object, ptr, ctx);
+}
+const char* PackedFixed64Parser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return FixedParser<uint64>(object, ptr, ctx);
+}
+const char* PackedSFixed64Parser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return FixedParser<int64>(object, ptr, ctx);
+}
+const char* PackedFloatParser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return FixedParser<float>(object, ptr, ctx);
+}
+const char* PackedDoubleParser(void* object, const char* ptr,
+ ParseContext* ctx) {
+ return FixedParser<double>(object, ptr, ctx);
+}
+
class UnknownFieldLiteParserHelper {
public:
explicit UnknownFieldLiteParserHelper(string* unknown) : unknown_(unknown) {}
@@ -470,20 +525,21 @@
std::memcpy(buffer, &value, 8);
unknown_->append(buffer, 8);
}
- ParseClosure AddLengthDelimited(uint32 num, uint32 size) {
- if (unknown_ == nullptr) return {NullParser, nullptr};
+ const char* ParseLengthDelimited(uint32 num, const char* ptr,
+ ParseContext* ctx) {
+ int size = ReadSize(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ if (unknown_ == nullptr) return ctx->Skip(ptr, size);
WriteVarint(num * 8 + 2, unknown_);
WriteVarint(size, unknown_);
- return {StringParser, unknown_};
+ return ctx->AppendString(ptr, size, unknown_);
}
- ParseClosure StartGroup(uint32 num) {
- if (unknown_ == nullptr) return {UnknownGroupLiteParse, nullptr};
- WriteVarint(num * 8 + 3, unknown_);
- return {UnknownGroupLiteParse, unknown_};
- }
- void EndGroup(uint32 num) {
- if (unknown_ == nullptr) return;
- WriteVarint(num * 8 + 4, unknown_);
+ const char* ParseGroup(uint32 num, const char* ptr, ParseContext* ctx) {
+ if (unknown_) WriteVarint(num * 8 + 3, unknown_);
+ ptr = ctx->ParseGroup(this, ptr, num * 8 + 3);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ if (unknown_) WriteVarint(num * 8 + 4, unknown_);
+ return ptr;
}
void AddFixed32(uint32 num, uint32 value) {
if (unknown_ == nullptr) return;
@@ -493,39 +549,24 @@
unknown_->append(buffer, 4);
}
+ const char* _InternalParse(const char* ptr, ParseContext* ctx) {
+ return WireFormatParser(*this, ptr, ctx);
+ }
+
private:
string* unknown_;
};
-const char* UnknownGroupLiteParse(const char* begin, const char* end,
- void* object, ParseContext* ctx) {
- UnknownFieldLiteParserHelper field_parser(static_cast<string*>(object));
- return WireFormatParser({UnknownGroupLiteParse, object}, field_parser, begin,
- end, ctx);
-}
-
-std::pair<const char*, bool> UnknownFieldParse(uint32 tag, ParseClosure parent,
- const char* begin,
- const char* end, string* unknown,
- ParseContext* ctx) {
+const char* UnknownGroupLiteParse(string* unknown, const char* ptr,
+ ParseContext* ctx) {
UnknownFieldLiteParserHelper field_parser(unknown);
- return FieldParser(tag, parent, field_parser, begin, end, ctx);
+ return WireFormatParser(field_parser, ptr, ctx);
}
-const char* SlowMapEntryParser(const char* begin, const char* end, void* object,
- internal::ParseContext* ctx) {
- ctx->extra_parse_data().payload.append(begin, end - begin);
- if (ctx->AtLimit()) {
- // Move payload out of extra_parse_data. Parsing maps could trigger
- // payload on recursive maps.
- string to_parse = std::move(ctx->extra_parse_data().payload);
- StringPiece chunk = to_parse;
- if (!ctx->extra_parse_data().parse_map(chunk.begin(), chunk.end(), object,
- ctx)) {
- return nullptr;
- }
- }
- return end;
+const char* UnknownFieldParse(uint32 tag, string* unknown, const char* ptr,
+ ParseContext* ctx) {
+ UnknownFieldLiteParserHelper field_parser(unknown);
+ return FieldParser(tag, field_parser, ptr, ctx);
}
} // namespace internal
diff --git a/src/google/protobuf/parse_context.h b/src/google/protobuf/parse_context.h
index 43e4144..f8122db 100644
--- a/src/google/protobuf/parse_context.h
+++ b/src/google/protobuf/parse_context.h
@@ -34,13 +34,18 @@
#include <cstring>
#include <string>
+#include <google/protobuf/parse_context.h>
#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/implicit_weak_message.h>
#include <google/protobuf/port.h>
+#include <google/protobuf/repeated_field.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/port_def.inc>
+
namespace google {
namespace protobuf {
@@ -52,24 +57,15 @@
// Template code below needs to know about the existence of these functions.
PROTOBUF_EXPORT void WriteVarint(uint32 num, uint64 val, std::string* s);
-PROTOBUF_EXPORT
-void WriteLengthDelimited(uint32 num, StringPiece val, std::string* s);
+PROTOBUF_EXPORT void WriteLengthDelimited(uint32 num, StringPiece val,
+ std::string* s);
// Inline because it is just forwarding to s->WriteVarint
inline void WriteVarint(uint32 num, uint64 val, UnknownFieldSet* s);
inline void WriteLengthDelimited(uint32 num, StringPiece val,
UnknownFieldSet* s);
-// ParseContext contains state that needs to be preserved across buffer seams.
-
-class ParseContext;
-
-// The parser works by composing elementary parse functions, that are generated
-// by the compiler, together to perform the full parse. To accomplish this the
-// functionality of the elementary parse function is slightly increased which
-// allows it to become composable.
-
-// The basic abstraction ParseContext is designed for is a slight modification
+// The basic abstraction the parser is designed for is a slight modification
// of the ZeroCopyInputStream (ZCIS) abstraction. A ZCIS presents a serialized
// stream as a series of buffers that concatenate to the full stream.
// Pictorially a ZCIS presents a stream in chunks like so
@@ -79,11 +75,11 @@
// chunk 3 [--------------]
//
// Where the '-' represent the bytes which are vertically lined up with the
-// bytes of the stream.
-// ParseContext requires its input to be presented similarily with the extra
-// property that the last kSlopBytes of a chunk overlaps with the first
-// kSlopBytes of the next chunk, or if there is no next chunk at least its still
-// valid to read those bytes. Again, pictorially, we now have
+// bytes of the stream. The proto parser requires its input to be presented
+// similarily with the extra
+// property that each chunk has kSlopBytes past its end that overlaps with the
+// first kSlopBytes of the next chunk, or if there is no next chunk at least its
+// still valid to read those bytes. Again, pictorially, we now have
//
// [---------------------------------------------------------------]
// [-------------------....] chunk 1
@@ -99,523 +95,473 @@
//
// The reason for this, admittedly, unconventional invariant is to ruthlessly
// optimize the protobuf parser. Having an overlap helps in two important ways.
-// Firstly it alleviates having to performing bounds checks, if a piece of code
-// will never read more than kSlopBytes. Secondly, and more importantly, the
-// protobuf wireformat is such that there is always a fresh start of a tag
-// within kSlopBytes. This allows the parser to exit parsing a chunk leaving
-// the parse on a position inside the overlap where a fresh tag starts.
+// Firstly it alleviates having to performing bounds checks if a piece of code
+// is guaranteed to not read more than kSlopBytes. Secondly, and more
+// importantly, the protobuf wireformat is such that reading a key/value pair is
+// always less than 16 bytes. This removes the need to change to next buffer in
+// the middle of reading primitive values. Hence there is no need to store and
+// load the current position.
-// The elementary parse function has the following signature
-
-typedef const char* (*ParseFunc)(const char* ptr, const char* end, void* object,
- ParseContext* ctx);
-
-// which parses the serialized data stored in the range [ptr, end) into object.
-// A parse function together with its object forms a callable closure.
-struct ParseClosure {
- ParseFunc func;
- void* object;
-
- // Pre-conditions
- // ptr < end is a non-empty range where ptr points to the start of a tag
- // and it's okay to read the bytes in [end, end + kSlopBytes).
- // Which will contain the bytes of the next chunk if the stream continues,
- // or undefined in which case the parse will be guaranteed to fail.
- //
- // Post-conditions
- // Parsed all tag/value pairs starting before end or if a group end
- // tag is encountered returns the pointer to that tag.
- // If a group end is encountered it verifies it matches the one that was
- // pushed and the stack is popped.
- // Otherwise it will parses the entire range pushing if end is inside one
- // of the children those are pushed on the stack.
- //
- // If an element is popped from the stack it ended on the correct end group
- // returns pointer after end-group tag (posibly in overlap, but the start
- // of end-group tag will be before end).
- // If the stack is the same or deeper, returns pointer in overlap region
- // (end <= retval < end + kSlopBytes).
- // All tag/value pairs between in [begin, retval) are parsed and retval
- // points to start of a tag.
- PROTOBUF_ALWAYS_INLINE // Don't pay for extra stack frame in debug mode
- const char*
- operator()(const char* ptr, const char* end, ParseContext* ctx) {
- GOOGLE_DCHECK(ptr < end);
- return func(ptr, end, object, ctx);
- }
-};
-
-// To fully parse a stream, a driver loop repeatedly calls the parse function
-// at the top of the stack, popping and resume parsing the parent message
-// according to the recursive structure of the wireformat. This loop will also
-// need to provide new buffer chunks and align the ptr correctly over the seams.
-// The point of this framework is that chunk refresh logic is located in the
-// outer loop, while the inner loop is almost free of it. The two code paths in
-// the parse code dealing with seams are located in fallback paths whose checks
-// are folded with input limit checks that are necessary anyway. In other words,
-// all the parser code that deals with seams is located in what would otherwise
-// be error paths of a parser that wouldn't need to deal with seams.
-
-class PROTOBUF_EXPORT ParseContext {
+class PROTOBUF_EXPORT EpsCopyInputStream {
public:
- enum {
- // Tag is atmost 5 bytes, varint is atmost 10 resulting in 15 bytes. We
- // choose
- // 16 bytes for the obvious reason of alignment.
- kSlopBytes = 16,
- // Inlined stack size
- kInlinedDepth = 15,
- };
+ enum { kSlopBytes = 16 };
- // Arghh!!! here be tech-debt dragons
- struct ExtraParseData {
- const DescriptorPool* pool = nullptr;
- MessageFactory* factory = nullptr;
+ explicit EpsCopyInputStream(bool enable_aliasing)
+ : aliasing_(enable_aliasing ? kOnPatch : kNoAliasing) {}
- // payload is used for MessageSetItem and maps
- std::string payload;
- bool (*parse_map)(const char* begin, const char* end, void* map_field,
- ParseContext* ctx);
-
- void SetEnumValidator(bool (*validator)(int), void* unknown,
- int field_num) {
- enum_validator = validator;
- unknown_fields = unknown;
- field_number = field_num;
- }
- void SetEnumValidatorArg(bool (*validator)(const void*, int),
- const void* arg, void* unknown, int field_num) {
- arg_enum_validator = {validator, arg};
- unknown_fields = unknown;
- field_number = field_num;
- }
- template <typename Unknown>
- bool ValidateEnum(int val) const {
- if (enum_validator(val)) return true;
- WriteVarint(field_number, val, static_cast<Unknown*>(unknown_fields));
- return false;
- }
- template <typename Unknown>
- bool ValidateEnumArg(int val) const {
- if (arg_enum_validator(val)) return true;
- WriteVarint(field_number, val, static_cast<Unknown*>(unknown_fields));
- return false;
- }
-
- void SetFieldName(const void* name) {
- unknown_fields = const_cast<void*>(name);
- }
- const char* FieldName() const {
- return static_cast<const char*>(unknown_fields);
- }
-
- union {
- bool (*enum_validator)(int);
- struct {
- bool operator()(int val) const { return validator(arg, val); }
- bool (*validator)(const void*, int);
- const void* arg;
- } arg_enum_validator;
- };
- void* unknown_fields;
- int field_number;
- // 0 means no aliasing. If not zero aliasing is the delta between the
- // ptr and the buffer that needs to be aliased. If the value is
- // kNoDelta (1) this means delta is actually 0 (we're working directly in
- // the buffer).
- enum { kNoDelta = 1 };
- std::uintptr_t aliasing = 0;
- };
-
- ExtraParseData& extra_parse_data() { return extra_parse_data_; }
- const ExtraParseData& extra_parse_data() const { return extra_parse_data_; }
-
- // Helpers to detect if a parse of length delimited field is completed.
- bool AtLimit() const { return limit_ == 0; }
- int32 CurrentLimit() const { return limit_; }
-
- // Initializes ParseContext with a specific recursion limit (rec_limit)
- explicit ParseContext(int rec_limit)
- : depth_(rec_limit),
- start_depth_(rec_limit),
- stack_(inline_stack_ + kInlinedDepth - rec_limit),
- inlined_depth_(std::max(0, rec_limit - kInlinedDepth)) {}
-
- ~ParseContext() {
- if (inlined_depth_ == -1) delete[] stack_;
- }
-
- void StartParse(ParseClosure parser) { parser_ = parser; }
-
- // Parses a chunk of memory given the current state of parse context (ie.
- // the active parser and stack) and overrun.
- // Pre-condition:
- // chunk_ is not empty.
- // limit_ > 0 (limit from begin) or -1 (no limit)
- // Post-condition:
- // returns true on success with overrun_ptr adjusted to the new value, or
- // false is the parse is finished. False means either a parse failure or
- // or because the top-level was terminated on a 0 or end-group tag in which
- // case overrun points to the position after the ending tag. You can call
- // EndedOnTag() to find if the parse failed due to an error or ended on
- // terminating tag.
- bool ParseRange(StringPiece chunk, int* overrun_ptr) {
- GOOGLE_DCHECK(!chunk.empty());
- int& overrun = *overrun_ptr;
- GOOGLE_DCHECK(overrun >= 0);
- if (overrun >= static_cast<int>(chunk.size())) {
- // This case can easily happen in patch buffers and we like to inline
- // this case.
- overrun -= chunk.size();
- return true;
- }
- auto res = ParseRangeWithLimit(chunk.begin() + overrun, chunk.end());
- overrun = res.second;
- return res.first;
- }
-
- bool ValidEnd(int overrun) { return depth_ == start_depth_ && overrun == 0; }
- bool EndedOnTag() const { return last_tag_minus_1_ != 0; }
- uint32 LastTag() const { return last_tag_minus_1_ + 1; }
-
- // Generically verifies for the slop region [begin, begin + kSlopBytes) if
- // the parse will be terminated by 0 or end-group tag. If true than you can
- // safely parse the slop region without having to load more data.
- bool ParseEndsInSlopRegion(const char* begin, int overrun) const;
-
- // Should only be called by Parse code.
-
- //////////////////////////////////////////////////////////////////////////////
- // Fast path helpers. These helpers maintain the state in parse context
- // through recursive calls. The whole design is to make this as minimal as
- // possible. Only recursion depth and limit are maintained at every recursion.
- //////////////////////////////////////////////////////////////////////////////
-
- bool ParseExactRange(ParseClosure parser, const char* begin,
- const char* end) {
- if (PROTOBUF_PREDICT_FALSE(--depth_ < 0)) return false;
- auto old_limit = limit_;
- limit_ = 0;
- auto ptr = begin;
- if (ptr < end) ptr = parser(ptr, end, this);
- if (ptr != end || EndedOnTag()) return false;
- limit_ = old_limit;
- ++depth_;
- return true;
- }
-
- // Returns a pair of the pointer the parse is left and a boolean indicating
- // if the group is still continuing.
- std::pair<const char*, bool> ParseGroup(uint32 tag, ParseClosure parser,
- const char* begin, const char* end,
- int* depth) {
- if (PROTOBUF_PREDICT_FALSE(--depth_ < 0)) return {};
- *depth = depth_;
- auto ptr = begin;
- if (ptr < end) ptr = parser(ptr, end, this);
- if (ptr == nullptr) return {};
- if (!EndedOnTag()) {
- // The group hasn't been terminated by an end-group and thus continues,
- // hence it must have ended because it crossed "end".
- GOOGLE_DCHECK(ptr >= end);
- return {ptr, true};
- }
- // Verify that the terminating tag matches the start group tag. As an extra
- // subtlety it could have been terminated by an end-group tag but in a
- // length delimited sub field of the group. So we must also check that depth
- // matches, if it doesn't match it means a length delimited subfield got
- // terminated by an end group which is an error.
- if (tag != last_tag_minus_1_ || *depth != depth_) return {};
- last_tag_minus_1_ = 0; // It must always be cleared.
- ++depth_;
- return {ptr, false};
- }
-
- void EndGroup(uint32 tag) {
- GOOGLE_DCHECK(tag == 0 || (tag & 7) == 4);
- // Because of the above assert last_tag_minus_1 is never set to 0, and the
- // caller can verify the child parser was terminated, by comparing to 0.
- last_tag_minus_1_ = tag - 1;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- // Slow path helper functions when a child crosses the "end" of range.
- // This is either an error (if limit_ = 0) OR we need to store state.
- // These functions manage the task of updating the state correctly.
- //////////////////////////////////////////////////////////////////////////////
-
- // Helper function called by generated code in case of a length delimited
- // field that is going to cross the boundary.
- const char* StoreAndTailCall(const char* ptr, const char* end,
- ParseClosure current_parser,
- ParseClosure child_parser, int32 size) {
- // At this point ptr could be past end. Hence a malicious size could
- // overflow.
- int64 safe_new_limit = size - static_cast<int64>(end - ptr);
- if (safe_new_limit > INT_MAX) return nullptr;
- GOOGLE_DCHECK(safe_new_limit > 0); // only call this if it's crossing end
- int32 new_limit = static_cast<int32>(safe_new_limit);
- int32 delta;
- if (limit_ != -1) {
- if (PROTOBUF_PREDICT_FALSE(new_limit > limit_)) return nullptr;
- delta = limit_ - new_limit;
+ void BackUp(const char* ptr) {
+ GOOGLE_DCHECK(ptr <= buffer_end_ + kSlopBytes);
+ int count;
+ if (next_chunk_ == buffer_) {
+ count = buffer_end_ + kSlopBytes - ptr;
} else {
- delta = -1; // special value
+ count = size_ + (buffer_end_ - ptr);
}
- limit_ = new_limit;
- // Save the current closure on the stack.
- if (!Push(current_parser, delta)) return nullptr;
- // Ensure the active state is set correctly.
- parser_ = child_parser;
- return ptr < end ? child_parser(ptr, end, this) : ptr;
+ if (count > 0) zcis_->BackUp(count);
}
- // Helper function for a child group that has crossed the boundary.
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
-#endif // defined(__GNUC__) && !defined(__clang__)
- bool StoreGroup(ParseClosure current_parser, ParseClosure child_parser,
- int depth, uint32 tag) {
- // The group must still read an end-group tag, so it can't be at a limit.
- // By having this check we ensure that when limit_ = 0 we can't end in some
- // deeper recursion. Hence ParseExactRange does not need to check for
- // matching depth.
- if (limit_ == 0) return false;
- if (depth == depth_) {
- // This child group is the active parser. The fast path code assumes
- // everything will be parsed within a chunk and doesn't modify
- // parse context in this case. We need to make the child parser active.
- parser_ = child_parser;
- }
- if (PROTOBUF_PREDICT_FALSE(depth < inlined_depth_)) SwitchStack();
- stack_[depth] = {current_parser, static_cast<int32>(~(tag >> 3))};
- return true;
+ // If return value is negative it's an error
+ PROTOBUF_MUST_USE_RESULT int PushLimit(const char* ptr, int limit) {
+ GOOGLE_DCHECK(limit >= 0);
+ limit += ptr - buffer_end_;
+ if (limit < 0) limit_end_ = buffer_end_ + limit;
+ auto old_limit = limit_;
+ limit_ = limit;
+ return old_limit - limit;
}
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
-#endif // defined(__GNUC__) && !defined(__clang__)
+
+ void PopLimit(int delta) {
+ // Ensure not to forget to check PushLimit return value
+ GOOGLE_DCHECK(delta >= 0);
+ // In a correct parse this addition can never overflow because all Pop's
+ // are paired with a Push. However on an incorrect parse this might not
+ // be the case. We use unsigned to prevent UB.
+ limit_ =
+ static_cast<unsigned int>(limit_) + static_cast<unsigned int>(delta);
+ limit_end_ = buffer_end_ + (std::min)(0, limit_);
+ }
+
+ PROTOBUF_MUST_USE_RESULT const char* Skip(const char* ptr, int size) {
+ if (size <= buffer_end_ + kSlopBytes - ptr) {
+ return ptr + size;
+ }
+ return SkipFallback(ptr, size);
+ }
+ PROTOBUF_MUST_USE_RESULT const char* ReadString(const char* ptr, int size,
+ std::string* s) {
+ if (size <= buffer_end_ + kSlopBytes - ptr) {
+ s->assign(ptr, size);
+ return ptr + size;
+ }
+ return ReadStringFallback(ptr, size, s);
+ }
+ PROTOBUF_MUST_USE_RESULT const char* AppendString(const char* ptr, int size,
+ std::string* s) {
+ if (size <= buffer_end_ + kSlopBytes - ptr) {
+ s->append(ptr, size);
+ return ptr + size;
+ }
+ return AppendStringFallback(ptr, size, s);
+ }
+
+ template <typename Tag, typename T>
+ PROTOBUF_MUST_USE_RESULT const char* ReadRepeatedFixed(const char* ptr,
+ Tag expected_tag,
+ RepeatedField<T>* out);
+
+ template <typename T>
+ PROTOBUF_MUST_USE_RESULT const char* ReadPackedFixed(const char* ptr,
+ int size,
+ RepeatedField<T>* out);
+ template <typename T, typename Add>
+ PROTOBUF_MUST_USE_RESULT const char* ReadPackedVarint(const char* ptr,
+ Add add);
+
+ int ConsecutiveBytes(const char* ptr) const { return limit_end_ - ptr; }
+ int BytesUntilLimit(const char* ptr) const {
+ return buffer_end_ - ptr + limit_;
+ }
+ bool AtLimit(const char* ptr) const {
+ return (ptr - buffer_end_ == limit_) ||
+ (next_chunk_ == nullptr && limit_ > 0 && ptr == buffer_end_);
+ }
+
+ protected:
+ // Returns true is limit (either an explicit limit or end of stream) is
+ // reached. It aligns *ptr across buffer seams.
+ // If limit is exceeded it returns true and ptr is set to null.
+ bool DoneWithCheck(const char** ptr, int d) {
+ GOOGLE_DCHECK(*ptr);
+ if (PROTOBUF_PREDICT_TRUE(*ptr < limit_end_)) return false;
+ // No need to fetch buffer if we ended on a limit in the slop region
+ if ((*ptr - buffer_end_) == limit_) return true;
+ auto res = DoneFallback(*ptr, d);
+ *ptr = res.first;
+ return res.second;
+ }
+
+ const char* InitFrom(StringPiece flat) {
+ if (flat.size() > kSlopBytes) {
+ limit_ = kSlopBytes;
+ limit_end_ = buffer_end_ = flat.end() - kSlopBytes;
+ if (aliasing_ == kOnPatch) aliasing_ = kNoDelta;
+ return flat.begin();
+ } else {
+ std::memcpy(buffer_, flat.begin(), flat.size());
+ limit_ = 0;
+ limit_end_ = buffer_end_ = buffer_ + flat.size();
+ next_chunk_ = nullptr;
+ if (aliasing_ == kOnPatch) {
+ aliasing_ = reinterpret_cast<std::uintptr_t>(flat.data()) -
+ reinterpret_cast<std::uintptr_t>(buffer_);
+ }
+ return buffer_;
+ }
+ }
+
+ const char* InitFrom(io::ZeroCopyInputStream* zcis);
+
+ const char* InitFrom(io::ZeroCopyInputStream* zcis, int limit) {
+ auto res = InitFrom(zcis);
+ limit_ = limit - (buffer_end_ - res);
+ limit_end_ = buffer_end_ + (std::min)(0, limit_);
+ return res;
+ }
private:
- // This the "active" or current parser.
- ParseClosure parser_;
+ const char* limit_end_ =
+ buffer_ + kSlopBytes; // buffer_end_ + min(limit_, 0)
+ const char* buffer_end_ = buffer_ + kSlopBytes;
+ const char* next_chunk_ = buffer_;
+ int size_;
+ int limit_ = INT_MAX; // relative to buffer_end_;
+ io::ZeroCopyInputStream* zcis_ = nullptr;
+ char buffer_[2 * kSlopBytes] = {};
+ enum { kNoAliasing = 0, kOnPatch = 1, kNoDelta = 2 };
+ std::uintptr_t aliasing_ = kNoAliasing;
+
+ std::pair<const char*, bool> DoneFallback(const char* ptr, int d);
+ const char* Next(int overrun, int d);
+ const char* SkipFallback(const char* ptr, int size);
+ const char* AppendStringFallback(const char* ptr, int size, std::string* str);
+ const char* ReadStringFallback(const char* ptr, int size, std::string* str);
+
+ template <typename A>
+ const char* AppendSize(const char* ptr, int size, const A& append) {
+ int chunk_size = buffer_end_ + kSlopBytes - ptr;
+ if (size > buffer_end_ - ptr + limit_) return nullptr;
+ do {
+ GOOGLE_DCHECK(size > chunk_size);
+ append(ptr, chunk_size);
+ ptr += chunk_size;
+ size -= chunk_size;
+ auto res = DoneFallback(ptr, -1);
+ if (res.second) {
+ return nullptr; // If done we passed the limit
+ }
+ ptr = res.first;
+ chunk_size = buffer_end_ + kSlopBytes - ptr;
+ } while (size > chunk_size);
+ append(ptr, size);
+ return ptr + size;
+ }
+
+ template <typename A>
+ const char* AppendUntilEnd(const char* ptr, const A& append) {
+ while (!DoneWithCheck(&ptr, -1)) {
+ append(ptr, limit_end_ - ptr);
+ ptr = limit_end_;
+ }
+ return ptr;
+ }
+
+ PROTOBUF_MUST_USE_RESULT const char* AppendString(const char* ptr,
+ std::string* str) {
+ return AppendUntilEnd(ptr,
+ [str](const char* p, int s) { str->append(p, s); });
+ }
+ friend class ImplicitWeakMessage;
+};
+
+// ParseContext holds all data that is global to the entire parse. Most
+// importantly it contains the input stream, but also recursion depth and also
+// stores the end group tag, in case a parser ended on a endgroup, to verify
+// matching start/end group tags.
+class PROTOBUF_EXPORT ParseContext
+ : public EpsCopyInputStream {
+ public:
+ struct Data {
+ const DescriptorPool* pool = nullptr;
+ MessageFactory* factory = nullptr;
+ };
+
+ template <typename... T>
+ ParseContext(int depth, bool aliasing, const char** start, T&&... args)
+ : EpsCopyInputStream(aliasing), depth_(depth) {
+ *start = InitFrom(std::forward<T>(args)...);
+ }
+
+ void TrackCorrectEnding() { group_depth_ = 0; }
+
+ bool Done(const char** ptr) { return DoneWithCheck(ptr, group_depth_); }
+ bool DoneNoSlopCheck(const char** ptr) { return DoneWithCheck(ptr, -1); }
+
+ int depth() const { return depth_; }
+ void SetLastTag(uint32 tag) { last_tag_minus_1_ = tag - 1; }
+ uint32 LastTagMinus1() const { return last_tag_minus_1_; }
+
+ bool AtLegitimateEnd(const char* ptr) const {
+ return ptr && AtLimit(ptr) && last_tag_minus_1_ == 0;
+ }
+
+ Data& data() { return data_; }
+ const Data& data() const { return data_; }
+
+ template <typename T>
+ PROTOBUF_MUST_USE_RESULT const char* ParseMessage(T* msg, const char* ptr);
+
+ template <typename T>
+ PROTOBUF_MUST_USE_RESULT const char* ParseGroup(T* msg, const char* ptr,
+ uint32 tag) {
+ if (--depth_ < 0) return nullptr;
+ group_depth_++;
+ ptr = msg->_InternalParse(ptr, this);
+ group_depth_--;
+ depth_++;
+ if (last_tag_minus_1_ != tag) return nullptr;
+ last_tag_minus_1_ = 0;
+ return ptr;
+ }
+
+ private:
// The context keeps an internal stack to keep track of the recursive
// part of the parse state.
// Current depth of the active parser, depth counts down.
// This is used to limit recursion depth (to prevent overflow on malicious
// data), but is also used to index in stack_ to store the current state.
int depth_;
- int32 limit_ = -1;
-
- // A state is on the stack to save it, in order to continue parsing after
- // child is done.
- struct State {
- ParseClosure parser;
- // This element describes how to adjust the parse state after finishing
- // the child. If the child was a length delimited field, delta describes
- // the limit relative to the child's limit (hence >= 0).
- // If child was a sub group limit contains ~field num (hence < 0) in order
- // to verify the group ended on a correct end tag. No limit adjusting.
- // Note above the sign of delta is meaningful
- int32 delta_or_group_num;
- };
- int start_depth_;
- // This is used to return the end group (or 0 tag) that terminated the parse.
- // Actually it contains last_tag minus 1. Which is either the start group tag
- // or -1. This member should always be zero and the caller should immediately
- // check this member to verify what state the parser ended on and clear its
- // value.
+ // Unfortunately necessary for the fringe case of ending on 0 or end-group tag
+ // in the last kSlopBytes of a ZeroCopyInputStream chunk.
+ int group_depth_ = INT_MIN;
uint32 last_tag_minus_1_ = 0;
-
- ExtraParseData extra_parse_data_;
- State* stack_;
- State inline_stack_[kInlinedDepth];
- int inlined_depth_;
-
- bool Push(ParseClosure parser, int32 delta) {
- GOOGLE_DCHECK(delta >= -1); // Make sure it's a valid len-delim
- if (PROTOBUF_PREDICT_FALSE(--depth_ < 0)) return false;
- if (PROTOBUF_PREDICT_FALSE(depth_ < inlined_depth_)) SwitchStack();
- stack_[depth_] = {parser, delta};
- return true;
- }
-
- State Pop() { return stack_[depth_++]; }
-
- void SwitchStack();
-
- // Parses a chunk of memory given the current state of parse context (ie.
- // the active parser and stack).
- // Pre-condition:
- // begin < end (non-empty range)
- // limit_ > 0 (limit from begin) or -1 (no limit)
- // Post-condition:
- // returns either (true, overrun) for a successful parse that can continue,
- // or (false, overrun) for a parse that can't continue. Either due to a
- // corrupt data (parse failure) or because the top-level was terminated on a
- // 0 or end-group tag in which case overrun points to the position after the
- // end.
- std::pair<bool, int> ParseRangeWithLimit(const char* begin, const char* end);
+ Data data_;
};
-// This is wrapper to parse a sequence of buffers without the overlap property,
-// like the sequence given by ZeroCopyInputStream (ZCIS) or ByteSource. This is
-// done by copying data around the seams, hence the name EpsCopyParser.
-// Pictorially if ZCIS presents a stream in chunks like so
-// [---------------------------------------------------------------]
-// [---------------------] chunk 1
-// [----------------------------] chunk 2
-// chunk 3 [--------------]
-// where '-' depicts bytes of the stream or chunks vertically alligned with the
-// corresponding bytes between stream and chunk.
-//
-// This class will present chunks to the ParseContext like this
-// [-----------------....] chunk 1
-// [----....] patch
-// [------------------------....] chunk 2
-// [----....] patch
-// chunk 3 [----------....]
-// patch [----****]
-// by using a fixed size buffer to patch over the seams. This requires
-// copying of an "epsilon" neighboorhood around the seams. In the picture above
-// dots mean bytes beyond the end of the new chunks. Each chunk is kSlopBytes
-// smalller as its original chunk (above depicted as 4 dots) and the number of
-// of chunks is doubled because each seam in the original stream introduces a
-// new patch.
-//
-// The algorithm is simple but not entirely trivial. Two complications arise
-// 1) The original chunk could be less than kSlopBytes. Hence we can't simply
-// chop the last kSlopBytes of a chunk.
-// 2) In some (infrequent) use cases, we don't necessarily parse unitl the end
-// of a stream, but instead the parse is terminated by 0 or end-group tag. If
-// this is allowed we must take care to leave the underlying stream at a
-// position precisely after the terminating tag. If this happens in the slop
-// region of a buffer we will already have loaded the next buffer. Not all
-// streams allow backing up to a previous buffer blocking us from leaving the
-// stream in the proper state. If terminating on 0 is allowed (in the old parser
-// this means a call to MergePartialFromCodedStream without a subsequent call to
-// ConsumedEntireMessage), this algorithm needs to ensure the parse won't end
-// in the slop region before moving the next buffer.
-//
-// The core idea of EpsCopyParser is to parse ranges except the last kSlopBytes
-// and store those in the patch buffer, until the next parse provides additional
-// data to fill the slop region. So parsing a range means first parsing the slop
-// bytes of the previous range using the new range to provide slop bytes for the
-// patch, followed by parsing the actual range except the last kSlopBytes and
-// store those. If no more data is available a call to Done finishes the parse
-// by parsing the remaining slopbytes.
-//
-// In order to deal with problem 1, we need to deal with the case that a new
-// chunk can be less or equal than kSlopBytes big. We can just copy the chunk
-// to the end and return (buffer, chunk->size). Pictorially
-// [--------] chunk 1
-// [--] chunk 2
-// [---] chunk 3
-// will become
-// [----....] chunk 1
-// [--....] patch (not full range of the patch buffer, only two hyphens)
-// [--] chunk 2 (too small so never parsed directly)
-// [---....] patch (not full range of the buffer, only three hyphens)
-// [---] chunk 3 (too small so never parsed directly)
-// [----****] patch (full range, last bytes are garbage)
-// Because of this the source (the dots in above) can overlap with the
-// destination buffer and so we have to use memmove.
-//
-// To solve problem 2, we use a generic parser together with knowledge of the
-// nesting from the side stack to verify if the parse will be terminated in the
-// slop region. If it terminates inside the slop region, we just parse it as
-// well. See ParseEndsInSlopRegion in ParseContext for the implementation. This
-// is only done if ensure_non_negative_skip is true, if it's false Skip() could
-// return a negative number.
-template <bool ensure_non_negative_skip>
-class EpsCopyParser {
- public:
- EpsCopyParser(ParseClosure parser, ParseContext* ctx) : ctx_(ctx) {
- ctx_->StartParse(parser);
- }
+template <typename T>
+T UnalignedLoad(const void* p) {
+ T res;
+ memcpy(&res, p, sizeof(T));
+ return res;
+}
- // Parse the bytes as provided by the non-empty range.
- // Returns true on a successful parse ready to accept more data, if there is
- // no more data call Done() to finish the parse.
- // Returns false if the parse is terminated. Termination is either due to a
- // parse error or due to termination on an end-group or 0 tag. You can call
- // EndedOnTag() on the underlying ParseContext to find out if the parse ended
- // correctly on a terminating tag.
- bool Parse(StringPiece range) {
- GOOGLE_DCHECK(!range.empty());
- auto size = range.size();
- if (size > kSlopBytes) {
- // The buffer is large enough to be able to parse the (size - kSlopBytes)
- // prefix directly. However we still need to parse the data in buffer_,
- // that holds the slop region of the previous buffer.
- if (overrun_ == kSlopBytes) {
- // We overrun the whole slop region of the previous buffer.
- // Optimization, we can skip the patch buffer.
- overrun_ = 0;
- } else {
- std::memcpy(buffer_ + kSlopBytes, range.begin(), kSlopBytes);
- if (!ParseRange({buffer_, kSlopBytes}, 0)) return false;
- }
- range.remove_suffix(kSlopBytes);
- } else {
- std::memcpy(buffer_ + kSlopBytes, range.begin(), size);
- range = {buffer_, size};
+// TODO(gerbens) Experiment with best implementation.
+// Clang unrolls loop and generating pretty good code on O2, gcc doesn't.
+// Unclear if we want 64 bit parse loop unrolled, inlined or opaque function
+// call. Hence experimentation is needed.
+// Important guarantee is that it doesn't read more than size bytes from p.
+template <int size, typename T>
+PROTOBUF_MUST_USE_RESULT const char* VarintParse(const char* p, T* out) {
+ T res = 1;
+ for (int i = 0; i < size; i++) {
+ T byte = static_cast<uint8>(p[i]);
+ res += (byte - 1) << (i * 7);
+ int j = i + 1;
+ if (PROTOBUF_PREDICT_TRUE(byte < 128)) {
+ *out = res;
+ return p + j;
}
- if (!ParseRange(range, size - kSlopBytes)) return false;
- std::memmove(buffer_, range.end(), kSlopBytes);
- if (ensure_non_negative_skip &&
- ctx_->ParseEndsInSlopRegion(buffer_, overrun_)) {
- // We care about leaving the stream at the right place and the stream will
- // indeed terminate, so just parse it.
- auto res = ParseRange({buffer_, kSlopBytes}, size);
- GOOGLE_DCHECK(!res);
- return false;
- }
- return true;
}
+ *out = 0;
+ return nullptr;
+}
- // Finish the parse by parsing the remaining data and verify success.
- bool Done() {
- return ParseRange({buffer_, kSlopBytes}, 0) && ctx_->ValidEnd(overrun_);
+// Decode 2 consecutive bytes of a varint. Two bytes must be available from
+// ptr. Returns ptr + 1 or ptr + 2 depending if the first byte had continuation
+// bit set. Stores The value of the varint shifted left by one.
+// If bit 15 of *res is set (equivalent to the continuation bits of both bytes
+// being set) the varint continues, otherwise the parse is done. On x86
+// movzx eax, word ptr [rdi]
+// movsx edx, al
+// and eax, edx
+// add eax, edx
+// adc rdi, 1
+inline const char* DecodeTwoBytes(const char* ptr, uint32* res) {
+ uint32_t y = UnalignedLoad<uint16>(ptr);
+ // Sign extend the low byte continuation bit
+ uint32_t x = static_cast<int8_t>(y);
+ y &= x; // Mask out the high byte iff no continuation
+ // This add is an amazing operation, it cancels the low byte continuation bit
+ // from y transferring it to the carry. Simultaneously it also shifts the 7
+ // LSB left by one tightly against high byte varint bits. Hence y now
+ // contains the unpacked value shifted left by 1.
+ y += x;
+ *res = y;
+ // If the addition above carried the high byte was part of the varint. Alas
+ // in c we don't have access to the carry, but a good optimizer compiles this
+ // down to a "adc" instruction.
+ return ptr + (y < x ? 2 : 1);
+}
+
+inline uint32 ReadSmallVarint(const char** ptr) {
+ uint32 res;
+ *ptr = DecodeTwoBytes(*ptr, &res);
+ return res >> 1;
+}
+
+std::pair<const char*, uint32> Parse32Fallback(const char* p, uint32 res);
+
+inline const char* _Parse32(const char* p, uint32* out) {
+ return VarintParse<5>(p, out);
+}
+
+inline const char* ReadTagOne(const char* p, uint32* out) {
+ *out = static_cast<uint8>(*p);
+ return p + 1;
+}
+
+inline const char* ReadTagTwo(const char* p, uint32* out) {
+ uint32 res = static_cast<uint8>(p[0]);
+ if (res < 128) { *out = res; return p + 1; }
+ uint32 byte = static_cast<uint8>(p[1]);
+ res += (byte << 7) - 128;
+ *out = res;
+ return p + 2;
+}
+
+inline const char* FinishReadTagOne(const char* p, uint32* tag) {
+ if (*tag & 128) {
+ uint32 tmp;
+ p = VarintParse<4>(p, &tmp);
+ *tag += ((tmp - 1) << 7);
}
+ return p;
+}
- // If the parse was terminated by a end-group or 0 tag. Skip returns the
- // offset where the parse left off relative to the start of the last range
- // parsed.
- // NOTE: This could be negative unless ensure_non_negative_skip is true.
- int Skip() {
- // The reason of ensure_non_negative_skip and ParseEndsInSlopRegion is that
- // the following assert holds. Which implies the stream doesn't need to
- // backup.
- GOOGLE_DCHECK(!ensure_non_negative_skip || overrun_ >= 0);
- return overrun_;
+inline const char* FinishReadTagTwo(const char* p, uint32* tag) {
+ if (*tag & (1 << 14)) {
+ uint32 tmp;
+ p = VarintParse<3>(p, &tmp);
+ *tag += ((tmp - 1) << 14);
}
+ return p;
+}
- private:
- constexpr static int kSlopBytes = ParseContext::kSlopBytes;
- // overrun_ stores where in the slop region of the previous parse the parse
- // was left off. This is used to start the parse of the next region at the
- // correct point. Initially overrun_ should be set to kSlopBytes which means
- // that the parse starts at precisely the beginning of new buffer provided.
- int overrun_ = kSlopBytes;
- // The first kSlopBytes of buffer_ contains the slop region of the previous
- // parsed region.
- char buffer_[2 * kSlopBytes] = {};
- ParseContext* ctx_;
+// Used for tags, could read up to 5 bytes which must be available.
+// Caller must ensure its safe to call.
+inline const char* ReadTag(const char* p, uint32* out) {
+ return _Parse32(p, out);
+}
- bool ParseRange(StringPiece range, int delta) {
- auto res = ctx_->ParseRange(range, &overrun_);
- if (!res) overrun_ += delta;
+std::pair<const char*, uint64> ParseVarint64Fallback(const char* p, uint64 res);
+
+// Used for reading varint wiretype values, could read up to 10 bytes.
+// Caller must ensure its safe to call.
+inline const char* ParseVarint64(const char* p, uint64* out) {
+ std::uint32_t tmp;
+ p = DecodeTwoBytes(p, &tmp);
+ if (PROTOBUF_PREDICT_TRUE(static_cast<int16>(tmp) >= 0)) {
+ *out = tmp >> 1;
+ return p;
+ }
+ auto x = ParseVarint64Fallback(p, tmp);
+ *out = x.second;
+ return x.first;
+}
+
+std::pair<const char*, int32> ReadSizeFallback(const char* p, uint32 first);
+// Used for tags, could read up to 5 bytes which must be available. Additionally
+// it makes sure the unsigned value fits a int32, otherwise returns nullptr.
+// Caller must ensure its safe to call.
+inline uint32 ReadSize(const char** pp) {
+ auto p = *pp;
+ uint32 res = static_cast<uint8>(p[0]);
+ if (res < 128) {
+ *pp = p + 1;
return res;
}
-};
+ auto x = ReadSizeFallback(p, res);
+ *pp = x.first;
+ return x.second;
+}
+
+// Some convenience functions to simplify the generated parse loop code.
+// Returning the value and updating the buffer pointer allows for nicer
+// function composition. We rely on the compiler to inline this.
+// Also in debug compiles having local scoped variables tend to generated
+// stack frames that scale as O(num fields).
+inline uint64 ReadVarint(const char** p) {
+ uint64 tmp;
+ *p = ParseVarint64(*p, &tmp);
+ return tmp;
+}
+
+inline int64 ReadVarintZigZag64(const char** p) {
+ uint64 tmp;
+ *p = ParseVarint64(*p, &tmp);
+ return WireFormatLite::ZigZagDecode64(tmp);
+}
+
+inline int32 ReadVarintZigZag32(const char** p) {
+ uint64 tmp;
+ *p = ParseVarint64(*p, &tmp);
+ return WireFormatLite::ZigZagDecode32(tmp);
+}
+
+template <typename T>
+PROTOBUF_MUST_USE_RESULT const char* ParseContext::ParseMessage(
+ T* msg, const char* ptr) {
+ int size = ReadSize(&ptr);
+ if (!ptr) return nullptr;
+ auto old = PushLimit(ptr, size);
+ if (--depth_ < 0 || old < 0) return nullptr;
+ ptr = msg->_InternalParse(ptr, this);
+ depth_++;
+ PopLimit(old);
+ if (last_tag_minus_1_ != 0) return nullptr;
+ return ptr;
+}
+
+template <typename T, typename Add>
+PROTOBUF_MUST_USE_RESULT const char* EpsCopyInputStream::ReadPackedVarint(
+ const char* ptr, Add add) {
+ int size = ReadSize(&ptr);
+ if (ptr == nullptr) return nullptr;
+ auto old = PushLimit(ptr, size);
+ if (old < 0) return nullptr;
+ while (!DoneWithCheck(&ptr, -1)) {
+ uint64 varint;
+ ptr = ParseVarint64(ptr, &varint);
+ if (!ptr) return nullptr;
+ add(varint);
+ }
+ PopLimit(old);
+ return ptr;
+}
+
+// Helper for verification of utf8
+PROTOBUF_EXPORT
+bool VerifyUTF8(StringPiece s, const char* field_name);
+
+// All the string parsers with or without UTF checking and for all CTypes.
+inline PROTOBUF_MUST_USE_RESULT const char* InlineGreedyStringParser(
+ std::string* s, const char* ptr, ParseContext* ctx) {
+ int size = ReadSize(&ptr);
+ if (!ptr) return nullptr;
+ return ctx->ReadString(ptr, size, s);
+}
+
+PROTOBUF_MUST_USE_RESULT const char* InlineGreedyStringParserUTF8(
+ std::string* s, const char* ptr, ParseContext* ctx, const char* field_name);
+PROTOBUF_MUST_USE_RESULT const char* InlineGreedyStringParserUTF8Verify(
+ std::string* s, const char* ptr, ParseContext* ctx, const char* field_name);
+
// Add any of the following lines to debug which parse function is failing.
#define GOOGLE_PROTOBUF_ASSERT_RETURN(predicate, ret) \
if (!(predicate)) { \
- /* raise(SIGINT); */ \
- /* GOOGLE_LOG(ERROR) << "Parse failure"; */ \
+ /* ::raise(SIGINT); */ \
+ /* GOOGLE_LOG(ERROR) << "Parse failure"; */ \
return ret; \
}
@@ -623,231 +569,119 @@
GOOGLE_PROTOBUF_ASSERT_RETURN(predicate, nullptr)
template <typename T>
-std::pair<const char*, bool> FieldParser(uint64 tag, ParseClosure parent,
- T field_parser, const char* begin,
- const char* end, ParseContext* ctx) {
- auto ptr = begin;
+PROTOBUF_MUST_USE_RESULT const char* FieldParser(uint64 tag, T& field_parser,
+ const char* ptr,
+ ParseContext* ctx) {
uint32 number = tag >> 3;
- if (PROTOBUF_PREDICT_FALSE(number == 0)) {
- GOOGLE_PROTOBUF_ASSERT_RETURN(tag == 0, {});
- // Special case scenario of 0 termination.
- ctx->EndGroup(tag);
- return {ptr, true};
- }
+ GOOGLE_PROTOBUF_PARSER_ASSERT(number != 0);
using WireType = internal::WireFormatLite::WireType;
switch (tag & 7) {
case WireType::WIRETYPE_VARINT: {
uint64 value;
- ptr = io::Parse64(ptr, &value);
- GOOGLE_PROTOBUF_ASSERT_RETURN(ptr != nullptr, {});
+ ptr = ParseVarint64(ptr, &value);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
field_parser.AddVarint(number, value);
break;
}
case WireType::WIRETYPE_FIXED64: {
- uint64 value = io::UnalignedLoad<uint64>(ptr);
+ uint64 value = UnalignedLoad<uint64>(ptr);
ptr += 8;
field_parser.AddFixed64(number, value);
break;
}
case WireType::WIRETYPE_LENGTH_DELIMITED: {
- int32 size;
- ptr = io::ReadSize(ptr, &size);
- GOOGLE_PROTOBUF_ASSERT_RETURN(ptr != nullptr, {});
- ParseClosure child = field_parser.AddLengthDelimited(number, size);
- if (size > end - ptr) {
- return {ctx->StoreAndTailCall(ptr, end, parent, child, size), true};
- }
- auto newend = ptr + size;
- GOOGLE_PROTOBUF_ASSERT_RETURN(ctx->ParseExactRange(child, ptr, newend),
- {});
- ptr = newend;
+ ptr = field_parser.ParseLengthDelimited(number, ptr, ctx);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
case WireType::WIRETYPE_START_GROUP: {
- int depth;
- ParseClosure child = field_parser.StartGroup(number);
- auto res = ctx->ParseGroup(tag, child, ptr, end, &depth);
- ptr = res.first;
- GOOGLE_PROTOBUF_ASSERT_RETURN(ptr != nullptr, {});
- if (res.second) {
- GOOGLE_PROTOBUF_ASSERT_RETURN(
- ctx->StoreGroup(parent, child, depth, tag), {});
- return {ptr, true};
- }
+ ptr = field_parser.ParseGroup(number, ptr, ctx);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
case WireType::WIRETYPE_END_GROUP: {
- field_parser.EndGroup(number);
- ctx->EndGroup(tag);
- return {ptr, true};
+ GOOGLE_LOG(FATAL) << "Can't happen";
+ break;
}
case WireType::WIRETYPE_FIXED32: {
- uint32 value = io::UnalignedLoad<uint32>(ptr);
+ uint32 value = UnalignedLoad<uint32>(ptr);
ptr += 4;
field_parser.AddFixed32(number, value);
break;
}
default:
- GOOGLE_PROTOBUF_ASSERT_RETURN(false, {});
- }
- GOOGLE_DCHECK(ptr != nullptr);
- return {ptr, false};
-}
-
-template <typename T>
-const char* WireFormatParser(ParseClosure parent, T field_parser,
- const char* begin, const char* end,
- ParseContext* ctx) {
- auto ptr = begin;
- while (ptr < end) {
- uint32 tag;
- ptr = io::Parse32(ptr, &tag);
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- auto res = FieldParser(tag, parent, field_parser, ptr, end, ctx);
- ptr = res.first;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ return nullptr;
}
return ptr;
}
-// Here are the elementary parsers for length delimited subfields that contain
-// plain data (ie not a protobuf). These are trivial as they don't recurse,
-// except for the UnknownGroupLiteParse that parses a group into a string.
-// Some functions need extra arguments that the function signature allows,
-// these are passed through variables in ParseContext::ExtraParseData that the
-// caller needs to set prior to the call.
-
-// The null parser does not do anything, but is useful as a substitute.
-PROTOBUF_EXPORT
-const char* NullParser(const char* begin, const char* end, void* object,
- ParseContext*);
-
-// Helper for verification of utf8
-PROTOBUF_EXPORT
-bool VerifyUTF8(StringPiece s, ParseContext* ctx);
-// All the string parsers with or without UTF checking and for all CTypes.
-PROTOBUF_EXPORT
-const char* StringParser(const char* begin, const char* end, void* object,
- ParseContext*);
-PROTOBUF_EXPORT
-const char* CordParser(const char* begin, const char* end, void* object,
- ParseContext*);
-PROTOBUF_EXPORT
-const char* StringPieceParser(const char* begin, const char* end, void* object,
- ParseContext*);
-PROTOBUF_EXPORT
-const char* StringParserUTF8(const char* begin, const char* end, void* object,
- ParseContext*);
-PROTOBUF_EXPORT
-const char* CordParserUTF8(const char* begin, const char* end, void* object,
- ParseContext*);
-PROTOBUF_EXPORT
-const char* StringPieceParserUTF8(const char* begin, const char* end,
- void* object, ParseContext*);
-PROTOBUF_EXPORT
-const char* StringParserUTF8Verify(const char* begin, const char* end,
- void* object, ParseContext*);
-PROTOBUF_EXPORT
-const char* CordParserUTF8Verify(const char* begin, const char* end,
- void* object, ParseContext*);
-PROTOBUF_EXPORT
-const char* StringPieceParserUTF8Verify(const char* begin, const char* end,
- void* object, ParseContext*);
-// Parsers that also eat the slopbytes if possible. Can only be called in a
-// ParseContext where limit_ is set properly.
-PROTOBUF_EXPORT
-const char* GreedyStringParser(const char* begin, const char* end, void* object,
- ParseContext*);
-PROTOBUF_EXPORT
-const char* GreedyStringParserUTF8(const char* begin, const char* end, void* object,
- ParseContext*);
-PROTOBUF_EXPORT
-const char* GreedyStringParserUTF8Verify(const char* begin, const char* end,
- void* object, ParseContext*);
-
-// This is the only recursive parser.
-PROTOBUF_EXPORT
-const char* UnknownGroupLiteParse(const char* begin, const char* end,
- void* object, ParseContext* ctx);
-// This is a helper to for the UnknownGroupLiteParse but is actually also
-// useful in the generated code. It uses overload on string* vs
-// UnknownFieldSet* to make the generated code isomorphic between full and lite.
-PROTOBUF_EXPORT
-std::pair<const char*, bool> UnknownFieldParse(uint32 tag, ParseClosure parent,
- const char* begin,
- const char* end, std::string* unknown,
- ParseContext* ctx);
+template <typename T>
+PROTOBUF_MUST_USE_RESULT const char* WireFormatParser(T& field_parser,
+ const char* ptr,
+ ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ uint32 tag;
+ ptr = ReadTag(ptr, &tag);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+ if (tag == 0 || (tag & 7) == 4) {
+ ctx->SetLastTag(tag);
+ return ptr;
+ }
+ ptr = FieldParser(tag, field_parser, ptr, ctx);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+ }
+ return ptr;
+}
// The packed parsers parse repeated numeric primitives directly into the
// corresponding field
// These are packed varints
-PROTOBUF_EXPORT
-const char* PackedInt32Parser(const char* begin, const char* end, void* object,
- ParseContext* ctx);
-PROTOBUF_EXPORT
-const char* PackedUInt32Parser(const char* begin, const char* end, void* object,
- ParseContext* ctx);
-PROTOBUF_EXPORT
-const char* PackedInt64Parser(const char* begin, const char* end, void* object,
- ParseContext* ctx);
-PROTOBUF_EXPORT
-const char* PackedUInt64Parser(const char* begin, const char* end, void* object,
- ParseContext* ctx);
-PROTOBUF_EXPORT
-const char* PackedSInt32Parser(const char* begin, const char* end, void* object,
- ParseContext* ctx);
-PROTOBUF_EXPORT
-const char* PackedSInt64Parser(const char* begin, const char* end, void* object,
- ParseContext* ctx);
-PROTOBUF_EXPORT
-const char* PackedBoolParser(const char* begin, const char* end, void* object,
- ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedInt32Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedUInt32Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedInt64Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedUInt64Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedSInt32Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedSInt64Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedEnumParser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedEnumParser(
+ void* object, const char* ptr, ParseContext* ctx, bool (*is_valid)(int),
+ std::string* unknown, int field_num);
+PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedEnumParserArg(
+ void* object, const char* ptr, ParseContext* ctx,
+ bool (*is_valid)(const void*, int), const void* data, std::string* unknown,
+ int field_num);
-// Enums in proto3 do not require verification
-PROTOBUF_EXPORT
-const char* PackedEnumParser(const char* begin, const char* end, void* object,
- ParseContext* ctx);
-// Enums in proto2 require verification. So an additional verification function
-// needs to be passed into ExtraParseData.
-// If it's a generated verification function we only need the function pointer.
-PROTOBUF_EXPORT
-const char* PackedValidEnumParserLite(const char* begin, const char* end,
- void* object, ParseContext* ctx);
-// If it's reflective we need a function that takes an additional argument.
-PROTOBUF_EXPORT
-const char* PackedValidEnumParserLiteArg(const char* begin, const char* end,
- void* object, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedBoolParser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedFixed32Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedSFixed32Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedFixed64Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedSFixed64Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedFloatParser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedDoubleParser(
+ void* object, const char* ptr, ParseContext* ctx);
-// These are the packed fixed field parsers.
-PROTOBUF_EXPORT
-const char* PackedFixed32Parser(const char* begin, const char* end,
- void* object, ParseContext* ctx);
-PROTOBUF_EXPORT
-const char* PackedSFixed32Parser(const char* begin, const char* end,
- void* object, ParseContext* ctx);
-PROTOBUF_EXPORT
-const char* PackedFixed64Parser(const char* begin, const char* end,
- void* object, ParseContext* ctx);
-PROTOBUF_EXPORT
-const char* PackedSFixed64Parser(const char* begin, const char* end,
- void* object, ParseContext* ctx);
-PROTOBUF_EXPORT
-const char* PackedFloatParser(const char* begin, const char* end, void* object,
- ParseContext* ctx);
-PROTOBUF_EXPORT
-const char* PackedDoubleParser(const char* begin, const char* end, void* object,
- ParseContext* ctx);
-
-// Maps key/value's are stored in a MapEntry length delimited field. If this
-// crosses a seam we fallback to first store in payload. The object points
-// to a MapField in which we parse the payload upon done (we detect this when
-// this function is called with limit_ == 0), by calling parse_map (also stored
-// in ctx) on the resulting string.
-PROTOBUF_EXPORT
-const char* SlowMapEntryParser(const char* begin, const char* end, void* object,
- internal::ParseContext* ctx);
+// This is the only recursive parser.
+PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* UnknownGroupLiteParse(
+ std::string* unknown, const char* ptr, ParseContext* ctx);
+// This is a helper to for the UnknownGroupLiteParse but is actually also
+// useful in the generated code. It uses overload on string* vs
+// UnknownFieldSet* to make the generated code isomorphic between full and lite.
+PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* UnknownFieldParse(
+ uint32 tag, std::string* unknown, const char* ptr, ParseContext* ctx);
} // namespace internal
} // namespace protobuf
diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc
index 24b3003..dcddb90 100644
--- a/src/google/protobuf/port_def.inc
+++ b/src/google/protobuf/port_def.inc
@@ -127,6 +127,9 @@
#ifdef PROTOC_EXPORT
#error PROTOC_EXPORT was previously defined
#endif
+#ifdef PROTOBUF_MUST_USE_RESULT
+#error PROTOBUF_MUST_USE_RESULT was previously defined
+#endif
#define PROTOBUF_NAMESPACE "google::protobuf"
@@ -134,6 +137,7 @@
#define PROTOBUF_DEPRECATED
#define PROTOBUF_DEPRECATED_MSG(x)
#define PROTOBUF_SECTION_VARIABLE(x)
+#define PROTOBUF_MUST_USE_RESULT
// ----------------------------------------------------------------------------
// Annotations: Some parts of the code have been annotated in ways that might
diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc
index b3177cd..f0cca4e 100644
--- a/src/google/protobuf/port_undef.inc
+++ b/src/google/protobuf/port_undef.inc
@@ -59,6 +59,7 @@
#undef PROTOBUF_FALLTHROUGH_INTENDED
#undef PROTOBUF_EXPORT
#undef PROTOC_EXPORT
+#undef PROTOBUF_MUST_USE_RESULT
// Restore macro that may have been #undef'd in port_def.inc.
#ifdef _MSC_VER
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
index 4214422..edb32a3 100644
--- a/src/google/protobuf/repeated_field.h
+++ b/src/google/protobuf/repeated_field.h
@@ -55,6 +55,7 @@
#include <iterator>
#include <limits>
#include <string>
+#include <type_traits>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/arena.h>
@@ -139,6 +140,9 @@
const Element& operator[](int index) const { return Get(index); }
Element& operator[](int index) { return *Mutable(index); }
+ const Element& at(int index) const;
+ Element& at(int index);
+
void Set(int index, const Element& value);
void Add(const Element& value);
// Appends a new element and return a pointer to it.
@@ -285,7 +289,7 @@
static const size_t kRepHeaderSize;
// We reuse the Rep* for an Arena* when total_size == 0, to avoid having to do
- // an allocation in the constructor when we have an Arena.
+ // an allocation in the constructor when we have an Arena.
union Pointer {
Pointer(Arena* a) : arena(a) {}
Arena* arena; // When total_size_ == 0.
@@ -412,6 +416,11 @@
typedef std::true_type type;
};
+template <typename T>
+struct IsMovable
+ : std::integral_constant<bool, std::is_move_constructible<T>::value &&
+ std::is_move_assignable<T>::value> {};
+
// This is the common base class for RepeatedPtrFields. It deals only in void*
// pointers. Users should not use this interface directly.
//
@@ -447,6 +456,11 @@
int size() const;
template <typename TypeHandler>
+ const typename TypeHandler::Type& at(int index) const;
+ template <typename TypeHandler>
+ typename TypeHandler::Type& at(int index);
+
+ template <typename TypeHandler>
typename TypeHandler::Type* Mutable(int index);
template <typename TypeHandler>
void Delete(int index);
@@ -476,9 +490,10 @@
inline void InternalSwap(RepeatedPtrFieldBase* other);
protected:
- template <typename TypeHandler>
- void Add(typename TypeHandler::Type&& value,
- typename std::enable_if<TypeHandler::Moveable>::type* dummy = NULL);
+ template <
+ typename TypeHandler,
+ typename std::enable_if<TypeHandler::Movable::value>::type* = nullptr>
+ void Add(typename TypeHandler::Type&& value);
template <typename TypeHandler>
void RemoveLast();
@@ -650,11 +665,14 @@
public:
typedef GenericType Type;
typedef GenericType WeakType;
- static const bool Moveable = false;
+ using Movable = IsMovable<GenericType>;
static inline GenericType* New(Arena* arena) {
return Arena::CreateMaybeMessage<Type>(arena);
}
+ static inline GenericType* New(Arena* arena, GenericType&& value) {
+ return Arena::Create<GenericType>(arena, std::move(value));
+ }
static inline GenericType* NewFromPrototype(const GenericType* prototype,
Arena* arena = NULL);
static inline void Delete(GenericType* value, Arena* arena) {
@@ -739,8 +757,7 @@
public:
typedef std::string Type;
typedef std::string WeakType;
- static const bool Moveable = std::is_move_constructible<Type>::value &&
- std::is_move_assignable<Type>::value;
+ using Movable = IsMovable<Type>;
static inline std::string* New(Arena* arena) {
return Arena::Create<std::string>(arena);
@@ -798,6 +815,9 @@
const Element& operator[](int index) const { return Get(index); }
Element& operator[](int index) { return *Mutable(index); }
+ const Element& at(int index) const;
+ Element& at(int index);
+
// Remove the last element in the array.
// Ownership of the element is retained by the array.
void RemoveLast();
@@ -1067,10 +1087,19 @@
ptr_(NULL) {
int reserve = internal::CalculateReserve(begin, end);
if (reserve != -1) {
- Reserve(reserve);
- for (; begin != end; ++begin) {
- AddAlreadyReserved(*begin);
+ if (reserve == 0) {
+ return;
}
+
+ Reserve(reserve);
+ // TODO(ckennelly): The compiler loses track of the buffer freshly
+ // allocated by Reserve() by the time we call elements, so it cannot
+ // guarantee that elements does not alias [begin(), end()).
+ //
+ // If restrict is available, annotating the pointer obtained from elements()
+ // causes this to lower to memcpy instead of memmove.
+ std::copy(begin, end, elements());
+ current_size_ = reserve;
} else {
for (; begin != end; ++begin) {
Add(*begin);
@@ -1180,6 +1209,20 @@
}
template <typename Element>
+inline const Element& RepeatedField<Element>::at(int index) const {
+ GOOGLE_CHECK_GE(index, 0);
+ GOOGLE_CHECK_LT(index, current_size_);
+ return elements()[index];
+}
+
+template <typename Element>
+inline Element& RepeatedField<Element>::at(int index) {
+ GOOGLE_CHECK_GE(index, 0);
+ GOOGLE_CHECK_LT(index, current_size_);
+ return elements()[index];
+}
+
+template <typename Element>
inline Element* RepeatedField<Element>::Mutable(int index) {
GOOGLE_DCHECK_GE(index, 0);
GOOGLE_DCHECK_LT(index, current_size_);
@@ -1516,6 +1559,21 @@
}
template <typename TypeHandler>
+inline const typename TypeHandler::Type& RepeatedPtrFieldBase::at(
+ int index) const {
+ GOOGLE_CHECK_GE(index, 0);
+ GOOGLE_CHECK_LT(index, current_size_);
+ return *cast<TypeHandler>(rep_->elements[index]);
+}
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type& RepeatedPtrFieldBase::at(int index) {
+ GOOGLE_CHECK_GE(index, 0);
+ GOOGLE_CHECK_LT(index, current_size_);
+ return *cast<TypeHandler>(rep_->elements[index]);
+}
+
+template <typename TypeHandler>
inline typename TypeHandler::Type*
RepeatedPtrFieldBase::Mutable(int index) {
GOOGLE_DCHECK_GE(index, 0);
@@ -1546,10 +1604,9 @@
return result;
}
-template <typename TypeHandler>
-inline void RepeatedPtrFieldBase::Add(
- typename TypeHandler::Type&& value,
- typename std::enable_if<TypeHandler::Moveable>::type*) {
+template <typename TypeHandler,
+ typename std::enable_if<TypeHandler::Movable::value>::type*>
+inline void RepeatedPtrFieldBase::Add(typename TypeHandler::Type&& value) {
if (rep_ != NULL && current_size_ < rep_->allocated_size) {
*cast<TypeHandler>(rep_->elements[current_size_++]) = std::move(value);
return;
@@ -1974,6 +2031,16 @@
return RepeatedPtrFieldBase::Get<TypeHandler>(index);
}
+template <typename Element>
+inline const Element& RepeatedPtrField<Element>::at(int index) const {
+ return RepeatedPtrFieldBase::at<TypeHandler>(index);
+}
+
+template <typename Element>
+inline Element& RepeatedPtrField<Element>::at(int index) {
+ return RepeatedPtrFieldBase::at<TypeHandler>(index);
+}
+
template <typename Element>
inline Element* RepeatedPtrField<Element>::Mutable(int index) {
diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc
index 033e343..d054ac9 100644
--- a/src/google/protobuf/repeated_field_unittest.cc
+++ b/src/google/protobuf/repeated_field_unittest.cc
@@ -38,6 +38,7 @@
#include <algorithm>
#include <limits>
#include <list>
+#include <type_traits>
#include <vector>
#include <google/protobuf/repeated_field.h>
@@ -71,26 +72,41 @@
EXPECT_FALSE(field.empty());
EXPECT_EQ(field.size(), 1);
EXPECT_EQ(field.Get(0), 5);
+ EXPECT_EQ(field.at(0), 5);
field.Add(42);
EXPECT_FALSE(field.empty());
EXPECT_EQ(field.size(), 2);
EXPECT_EQ(field.Get(0), 5);
+ EXPECT_EQ(field.at(0), 5);
EXPECT_EQ(field.Get(1), 42);
+ EXPECT_EQ(field.at(1), 42);
field.Set(1, 23);
EXPECT_FALSE(field.empty());
EXPECT_EQ(field.size(), 2);
EXPECT_EQ(field.Get(0), 5);
+ EXPECT_EQ(field.at(0), 5);
EXPECT_EQ(field.Get(1), 23);
+ EXPECT_EQ(field.at(1), 23);
+
+ field.at(1) = 25;
+
+ EXPECT_FALSE(field.empty());
+ EXPECT_EQ(field.size(), 2);
+ EXPECT_EQ(field.Get(0), 5);
+ EXPECT_EQ(field.at(0), 5);
+ EXPECT_EQ(field.Get(1), 25);
+ EXPECT_EQ(field.at(1), 25);
field.RemoveLast();
EXPECT_FALSE(field.empty());
EXPECT_EQ(field.size(), 1);
EXPECT_EQ(field.Get(0), 5);
+ EXPECT_EQ(field.at(0), 5);
field.Clear();
@@ -341,6 +357,9 @@
TEST(RepeatedField, IteratorConstruct) {
std::vector<int> values;
+ RepeatedField<int> empty(values.begin(), values.end());
+ ASSERT_EQ(values.size(), empty.size());
+
values.push_back(1);
values.push_back(2);
@@ -516,6 +535,48 @@
}
}
+TEST(Movable, Works) {
+ class NonMoveConstructible {
+ public:
+ NonMoveConstructible(NonMoveConstructible&&) = delete;
+ NonMoveConstructible& operator=(NonMoveConstructible&&) { return *this; }
+ };
+ class NonMoveAssignable {
+ public:
+ NonMoveAssignable(NonMoveAssignable&&) {}
+ NonMoveAssignable& operator=(NonMoveConstructible&&) = delete;
+ };
+ class NonMovable {
+ public:
+ NonMovable(NonMovable&&) = delete;
+ NonMovable& operator=(NonMovable&&) = delete;
+ };
+
+ EXPECT_TRUE(internal::IsMovable<string>::value);
+
+ EXPECT_FALSE(std::is_move_constructible<NonMoveConstructible>::value);
+ EXPECT_TRUE(std::is_move_assignable<NonMoveConstructible>::value);
+ EXPECT_FALSE(internal::IsMovable<NonMoveConstructible>::value);
+
+ EXPECT_TRUE(std::is_move_constructible<NonMoveAssignable>::value);
+ EXPECT_FALSE(std::is_move_assignable<NonMoveAssignable>::value);
+ EXPECT_FALSE(internal::IsMovable<NonMoveAssignable>::value);
+
+ EXPECT_FALSE(internal::IsMovable<NonMovable>::value);
+}
+
+TEST(RepeatedField, MoveAdd) {
+ RepeatedPtrField<TestAllTypes> field;
+ TestAllTypes test_all_types;
+ auto* optional_nested_message =
+ test_all_types.mutable_optional_nested_message();
+ optional_nested_message->set_bb(42);
+ field.Add(std::move(test_all_types));
+
+ EXPECT_EQ(optional_nested_message,
+ field.Mutable(0)->mutable_optional_nested_message());
+}
+
TEST(RepeatedField, MutableDataIsMutable) {
RepeatedField<int> field;
field.Add(1);
@@ -633,26 +694,32 @@
EXPECT_FALSE(field.empty());
EXPECT_EQ(field.size(), 1);
EXPECT_EQ(field.Get(0), "foo");
+ EXPECT_EQ(field.at(0), "foo");
field.Add()->assign("bar");
EXPECT_FALSE(field.empty());
EXPECT_EQ(field.size(), 2);
EXPECT_EQ(field.Get(0), "foo");
+ EXPECT_EQ(field.at(0), "foo");
EXPECT_EQ(field.Get(1), "bar");
+ EXPECT_EQ(field.at(1), "bar");
field.Mutable(1)->assign("baz");
EXPECT_FALSE(field.empty());
EXPECT_EQ(field.size(), 2);
EXPECT_EQ(field.Get(0), "foo");
+ EXPECT_EQ(field.at(0), "foo");
EXPECT_EQ(field.Get(1), "baz");
+ EXPECT_EQ(field.at(1), "baz");
field.RemoveLast();
EXPECT_FALSE(field.empty());
EXPECT_EQ(field.size(), 1);
EXPECT_EQ(field.Get(0), "foo");
+ EXPECT_EQ(field.at(0), "foo");
field.Clear();
diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc
index 89faa46..566eed7 100644
--- a/src/google/protobuf/source_context.pb.cc
+++ b/src/google/protobuf/source_context.pb.cc
@@ -42,9 +42,9 @@
::google::protobuf::internal::InitSCC(&scc_info_SourceContext_google_2fprotobuf_2fsource_5fcontext_2eproto.base);
}
-::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fsource_5fcontext_2eproto[1];
-constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto = nullptr;
-constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto = nullptr;
+static ::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fsource_5fcontext_2eproto[1];
+static constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto = nullptr;
+static constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto = nullptr;
const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2fsource_5fcontext_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
~0u, // no _has_bits_
@@ -62,7 +62,7 @@
reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_SourceContext_default_instance_),
};
-::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fsource_5fcontext_2eproto = {
+static ::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fsource_5fcontext_2eproto = {
{}, AddDescriptors_google_2fprotobuf_2fsource_5fcontext_2eproto, "google/protobuf/source_context.proto", schemas,
file_default_instances, TableStruct_google_2fprotobuf_2fsource_5fcontext_2eproto::offsets,
file_level_metadata_google_2fprotobuf_2fsource_5fcontext_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto, file_level_service_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto,
@@ -77,7 +77,7 @@
"text\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTy"
"pesb\006proto3"
;
-::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto = {
+static ::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto = {
false, InitDefaults_google_2fprotobuf_2fsource_5fcontext_2eproto,
descriptor_table_protodef_google_2fprotobuf_2fsource_5fcontext_2eproto,
"google/protobuf/source_context.proto", &assign_descriptors_table_google_2fprotobuf_2fsource_5fcontext_2eproto, 251,
@@ -158,56 +158,33 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* SourceContext::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<SourceContext*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* SourceContext::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// string file_name = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(mutable_file_name(), ptr, ctx, "google.protobuf.SourceContext.file_name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.SourceContext.file_name");
- object = msg->mutable_file_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool SourceContext::MergePartialFromCodedStream(
diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h
index 4ed8997..ae50e80 100644
--- a/src/google/protobuf/source_context.pb.h
+++ b/src/google/protobuf/source_context.pb.h
@@ -31,6 +31,13 @@
#include <google/protobuf/repeated_field.h> // IWYU pragma: export
#include <google/protobuf/extension_set.h> // IWYU pragma: export
#include <google/protobuf/unknown_field_set.h>
+namespace google {
+namespace protobuf {
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+} // namespace protobuf
+} // namespace google
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fsource_5fcontext_2eproto PROTOBUF_EXPORT
@@ -124,8 +131,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -137,10 +143,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(SourceContext* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.SourceContext";
+ }
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return nullptr;
diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc
index c0fd3f3..b107e5d 100644
--- a/src/google/protobuf/struct.pb.cc
+++ b/src/google/protobuf/struct.pb.cc
@@ -78,9 +78,9 @@
::google::protobuf::internal::InitSCC(&scc_info_ListValue_google_2fprotobuf_2fstruct_2eproto.base);
}
-::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fstruct_2eproto[4];
-const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto[1];
-constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fstruct_2eproto = nullptr;
+static ::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fstruct_2eproto[4];
+static const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto[1];
+static constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fstruct_2eproto = nullptr;
const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2fstruct_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
PROTOBUF_FIELD_OFFSET(::google::protobuf::Struct_FieldsEntry_DoNotUse, _has_bits_),
@@ -131,7 +131,7 @@
reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_ListValue_default_instance_),
};
-::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fstruct_2eproto = {
+static ::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fstruct_2eproto = {
{}, AddDescriptors_google_2fprotobuf_2fstruct_2eproto, "google/protobuf/struct.proto", schemas,
file_default_instances, TableStruct_google_2fprotobuf_2fstruct_2eproto::offsets,
file_level_metadata_google_2fprotobuf_2fstruct_2eproto, 4, file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto, file_level_service_descriptors_google_2fprotobuf_2fstruct_2eproto,
@@ -156,7 +156,7 @@
"\252\002\036Google.Protobuf.WellKnownTypesb\006proto"
"3"
;
-::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fstruct_2eproto = {
+static ::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fstruct_2eproto = {
false, InitDefaults_google_2fprotobuf_2fstruct_2eproto,
descriptor_table_protodef_google_2fprotobuf_2fstruct_2eproto,
"google/protobuf/struct.proto", &assign_descriptors_table_google_2fprotobuf_2fstruct_2eproto, 641,
@@ -204,25 +204,6 @@
::google::protobuf::Message::MergeFrom(other);
}
-#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-bool Struct_FieldsEntry_DoNotUse::_ParseMap(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx) {
- using MF = ::google::protobuf::internal::MapField<
- Struct_FieldsEntry_DoNotUse, EntryKeyType, EntryValueType,
- kEntryKeyFieldType, kEntryValueFieldType,
- kEntryDefaultEnumValue>;
- auto mf = static_cast<MF*>(object);
- Parser<MF, ::google::protobuf::Map<EntryKeyType, EntryValueType>> parser(mf);
-#define DO_(x) if (!(x)) return false
- DO_(parser.ParseMap(begin, end));
- DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
- parser.key().data(), static_cast<int>(parser.key().length()),
- ::google::protobuf::internal::WireFormatLite::PARSE,
- "google.protobuf.Struct.FieldsEntry.key"));
-#undef DO_
- return true;
-}
-#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-
// ===================================================================
@@ -297,55 +278,36 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* Struct::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<Struct*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* Struct::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// map<string, .google.protobuf.Value> fields = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(&fields_, ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::internal::SlowMapEntryParser;
- auto parse_map = ::google::protobuf::Struct_FieldsEntry_DoNotUse::_ParseMap;
- ctx->extra_parse_data().payload.clear();
- ctx->extra_parse_data().parse_map = parse_map;
- object = &msg->fields_;
- if (size > end - ptr) goto len_delim_till_end;
- auto newend = ptr + size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(parse_map(ptr, newend, object, ctx));
- ptr = newend;
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool Struct::MergePartialFromCodedStream(
@@ -434,25 +396,17 @@
items[static_cast<ptrdiff_t>(n)] = SortItem(&*it);
}
::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less());
- ::std::unique_ptr<Struct_FieldsEntry_DoNotUse> entry;
for (size_type i = 0; i < n; i++) {
- entry.reset(fields_.NewEntryWrapper(items[static_cast<ptrdiff_t>(i)]->first, items[static_cast<ptrdiff_t>(i)]->second));
- ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(1, *entry, output);
- if (entry->GetArena() != nullptr) {
- entry.release();
- }
+ Struct_FieldsEntry_DoNotUse::MapEntryWrapper entry(nullptr, items[static_cast<ptrdiff_t>(i)]->first, items[static_cast<ptrdiff_t>(i)]->second);
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(1, entry, output);
Utf8Check::Check(&(*items[static_cast<ptrdiff_t>(i)]));
}
} else {
- ::std::unique_ptr<Struct_FieldsEntry_DoNotUse> entry;
for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
it = this->fields().begin();
it != this->fields().end(); ++it) {
- entry.reset(fields_.NewEntryWrapper(it->first, it->second));
- ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(1, *entry, output);
- if (entry->GetArena() != nullptr) {
- entry.release();
- }
+ Struct_FieldsEntry_DoNotUse::MapEntryWrapper entry(nullptr, it->first, it->second);
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(1, entry, output);
Utf8Check::Check(&(*it));
}
}
@@ -498,25 +452,17 @@
items[static_cast<ptrdiff_t>(n)] = SortItem(&*it);
}
::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less());
- ::std::unique_ptr<Struct_FieldsEntry_DoNotUse> entry;
for (size_type i = 0; i < n; i++) {
- entry.reset(fields_.NewEntryWrapper(items[static_cast<ptrdiff_t>(i)]->first, items[static_cast<ptrdiff_t>(i)]->second));
- target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessageNoVirtualToArray(1, *entry, target);
- if (entry->GetArena() != nullptr) {
- entry.release();
- }
+ Struct_FieldsEntry_DoNotUse::MapEntryWrapper entry(nullptr, items[static_cast<ptrdiff_t>(i)]->first, items[static_cast<ptrdiff_t>(i)]->second);
+ target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessageNoVirtualToArray(1, entry, target);
Utf8Check::Check(&(*items[static_cast<ptrdiff_t>(i)]));
}
} else {
- ::std::unique_ptr<Struct_FieldsEntry_DoNotUse> entry;
for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
it = this->fields().begin();
it != this->fields().end(); ++it) {
- entry.reset(fields_.NewEntryWrapper(it->first, it->second));
- target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessageNoVirtualToArray(1, *entry, target);
- if (entry->GetArena() != nullptr) {
- entry.release();
- }
+ Struct_FieldsEntry_DoNotUse::MapEntryWrapper entry(nullptr, it->first, it->second);
+ target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessageNoVirtualToArray(1, entry, target);
Utf8Check::Check(&(*it));
}
}
@@ -546,21 +492,12 @@
// map<string, .google.protobuf.Value> fields = 1;
total_size += 1 *
::google::protobuf::internal::FromIntSize(this->fields_size());
- {
- ::std::unique_ptr<Struct_FieldsEntry_DoNotUse> entry;
- for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
- it = this->fields().begin();
- it != this->fields().end(); ++it) {
- if (entry.get() != nullptr && entry->GetArena() != nullptr) {
- entry.release();
- }
- entry.reset(fields_.NewEntryWrapper(it->first, it->second));
- total_size += ::google::protobuf::internal::WireFormatLite::
- MessageSizeNoVirtual(*entry);
- }
- if (entry.get() != nullptr && entry->GetArena() != nullptr) {
- entry.release();
- }
+ for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
+ it = this->fields().begin();
+ it != this->fields().end(); ++it) {
+ Struct_FieldsEntry_DoNotUse::MapEntryWrapper entry(nullptr, it->first, it->second);
+ total_size += ::google::protobuf::internal::WireFormatLite::
+ MessageSizeNoVirtual(entry);
}
int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
@@ -841,104 +778,69 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* Value::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<Value*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* Value::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// .google.protobuf.NullValue null_value = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
- msg->set_null_value(static_cast<::google::protobuf::NullValue>(val));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ set_null_value(static_cast<::google::protobuf::NullValue>(val));
break;
}
// double number_value = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 17) goto handle_unusual;
- msg->set_number_value(::google::protobuf::io::UnalignedLoad<double>(ptr));
+ set_number_value(::google::protobuf::internal::UnalignedLoad<double>(ptr));
ptr += sizeof(double);
break;
}
// string string_value = 3;
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(mutable_string_value(), ptr, ctx, "google.protobuf.Value.string_value");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.Value.string_value");
- object = msg->mutable_string_value();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// bool bool_value = 4;
case 4: {
if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
- msg->set_bool_value(::google::protobuf::internal::ReadVarint(&ptr));
+ set_bool_value(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// .google.protobuf.Struct struct_value = 5;
case 5: {
if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(mutable_struct_value(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::Struct::_InternalParse;
- object = msg->mutable_struct_value();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
break;
}
// .google.protobuf.ListValue list_value = 6;
case 6: {
if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(mutable_list_value(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::ListValue::_InternalParse;
- object = msg->mutable_list_value();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool Value::MergePartialFromCodedStream(
@@ -1393,52 +1295,36 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* ListValue::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<ListValue*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* ListValue::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// repeated .google.protobuf.Value values = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_values(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::Value::_InternalParse;
- object = msg->add_values();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool ListValue::MergePartialFromCodedStream(
diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h
index 7d8040d..204edc3 100644
--- a/src/google/protobuf/struct.pb.h
+++ b/src/google/protobuf/struct.pb.h
@@ -35,6 +35,13 @@
#include <google/protobuf/map_field_inl.h>
#include <google/protobuf/generated_enum_reflection.h>
#include <google/protobuf/unknown_field_set.h>
+namespace google {
+namespace protobuf {
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+} // namespace protobuf
+} // namespace google
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fstruct_2eproto PROTOBUF_EXPORT
@@ -81,9 +88,9 @@
NullValue_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
PROTOBUF_EXPORT bool NullValue_IsValid(int value);
-const NullValue NullValue_MIN = NULL_VALUE;
-const NullValue NullValue_MAX = NULL_VALUE;
-const int NullValue_ARRAYSIZE = NullValue_MAX + 1;
+constexpr NullValue NullValue_MIN = NULL_VALUE;
+constexpr NullValue NullValue_MAX = NULL_VALUE;
+constexpr int NullValue_ARRAYSIZE = NullValue_MAX + 1;
PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* NullValue_descriptor();
inline const ::std::string& NullValue_Name(NullValue value) {
@@ -103,9 +110,6 @@
::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE,
0 > {
public:
-#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-static bool _ParseMap(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
-#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
typedef ::google::protobuf::internal::MapEntry<Struct_FieldsEntry_DoNotUse,
::std::string, ::google::protobuf::Value,
::google::protobuf::internal::WireFormatLite::TYPE_STRING,
@@ -191,8 +195,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -204,10 +207,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Struct* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.Struct";
+ }
protected:
explicit Struct(::google::protobuf::Arena* arena);
private:
@@ -337,8 +344,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -350,10 +356,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Value* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.Value";
+ }
protected:
explicit Value(::google::protobuf::Arena* arena);
private:
@@ -556,8 +566,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -569,10 +578,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(ListValue* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.ListValue";
+ }
protected:
explicit ListValue(::google::protobuf::Arena* arena);
private:
diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h
index d87e993..5b8e85d 100644
--- a/src/google/protobuf/stubs/port.h
+++ b/src/google/protobuf/stubs/port.h
@@ -432,7 +432,8 @@
} // namespace google
#ifdef PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-#define GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER 1
+#define GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER \
+ PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
#else
#define GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER 0
#endif
diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc
index 1339449..c660315 100644
--- a/src/google/protobuf/text_format.cc
+++ b/src/google/protobuf/text_format.cc
@@ -53,6 +53,7 @@
#include <google/protobuf/descriptor.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/map_field.h>
+#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/unknown_field_set.h>
#include <google/protobuf/wire_format_lite.h>
@@ -101,8 +102,7 @@
printer.PrintToString(*this, &debug_string);
// Single line mode currently might have an extra space at the end.
- if (debug_string.size() > 0 &&
- debug_string[debug_string.size() - 1] == ' ') {
+ if (debug_string.size() > 0 && debug_string[debug_string.size() - 1] == ' ') {
debug_string.resize(debug_string.size() - 1);
}
@@ -121,14 +121,12 @@
return debug_string;
}
-void Message::PrintDebugString() const {
- printf("%s", DebugString().c_str());
-}
+void Message::PrintDebugString() const { printf("%s", DebugString().c_str()); }
// ===========================================================================
// Implementation of the parse information tree class.
-TextFormat::ParseInfoTree::ParseInfoTree() { }
+TextFormat::ParseInfoTree::ParseInfoTree() {}
TextFormat::ParseInfoTree::~ParseInfoTree() {
// Remove any nested information trees, as they are owned by this tree.
@@ -138,8 +136,7 @@
}
void TextFormat::ParseInfoTree::RecordLocation(
- const FieldDescriptor* field,
- TextFormat::ParseLocation location) {
+ const FieldDescriptor* field, TextFormat::ParseLocation location) {
locations_[field].push_back(location);
}
@@ -154,7 +151,9 @@
}
void CheckFieldIndex(const FieldDescriptor* field, int index) {
- if (field == NULL) { return; }
+ if (field == NULL) {
+ return;
+ }
if (field->is_repeated() && index == -1) {
GOOGLE_LOG(DFATAL) << "Index must be in range of repeated field values. "
@@ -168,7 +167,9 @@
TextFormat::ParseLocation TextFormat::ParseInfoTree::GetLocation(
const FieldDescriptor* field, int index) const {
CheckFieldIndex(field, index);
- if (index == -1) { index = 0; }
+ if (index == -1) {
+ index = 0;
+ }
const std::vector<TextFormat::ParseLocation>* locations =
FindOrNull(locations_, field);
@@ -182,7 +183,9 @@
TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested(
const FieldDescriptor* field, int index) const {
CheckFieldIndex(field, index);
- if (index == -1) { index = 0; }
+ if (index == -1) {
+ index = 0;
+ }
const std::vector<TextFormat::ParseInfoTree*>* trees =
FindOrNull(nested_, field);
@@ -222,11 +225,14 @@
// Makes code slightly more readable. The meaning of "DO(foo)" is
// "Execute foo and fail if it fails.", where failure is indicated by
// returning false. Borrowed from parser.cc (Thanks Kenton!).
-#define DO(STATEMENT) if (STATEMENT) {} else return false
+#define DO(STATEMENT) \
+ if (STATEMENT) { \
+ } else { \
+ return false; \
+ }
class TextFormat::Parser::ParserImpl {
public:
-
// Determines if repeated values for non-repeated fields and
// oneofs are permitted, e.g., the string "foo: 1 foo: 2" for a
// required/optional field named "foo", or "baz: 1 qux: 2"
@@ -239,31 +245,27 @@
ParserImpl(const Descriptor* root_message_type,
io::ZeroCopyInputStream* input_stream,
io::ErrorCollector* error_collector,
- const TextFormat::Finder* finder,
- ParseInfoTree* parse_info_tree,
+ const TextFormat::Finder* finder, ParseInfoTree* parse_info_tree,
SingularOverwritePolicy singular_overwrite_policy,
- bool allow_case_insensitive_field,
- bool allow_unknown_field,
- bool allow_unknown_extension,
- bool allow_unknown_enum,
- bool allow_field_number,
- bool allow_relaxed_whitespace,
- bool allow_partial)
- : error_collector_(error_collector),
- finder_(finder),
- parse_info_tree_(parse_info_tree),
- tokenizer_error_collector_(this),
- tokenizer_(input_stream, &tokenizer_error_collector_),
- root_message_type_(root_message_type),
- singular_overwrite_policy_(singular_overwrite_policy),
- allow_case_insensitive_field_(allow_case_insensitive_field),
- allow_unknown_field_(allow_unknown_field),
- allow_unknown_extension_(allow_unknown_extension),
- allow_unknown_enum_(allow_unknown_enum),
- allow_field_number_(allow_field_number),
- allow_partial_(allow_partial),
- recursion_budget_(io::CodedInputStream::GetDefaultRecursionLimit()),
- had_errors_(false) {
+ bool allow_case_insensitive_field, bool allow_unknown_field,
+ bool allow_unknown_extension, bool allow_unknown_enum,
+ bool allow_field_number, bool allow_relaxed_whitespace,
+ bool allow_partial, int recursion_limit)
+ : error_collector_(error_collector),
+ finder_(finder),
+ parse_info_tree_(parse_info_tree),
+ tokenizer_error_collector_(this),
+ tokenizer_(input_stream, &tokenizer_error_collector_),
+ root_message_type_(root_message_type),
+ singular_overwrite_policy_(singular_overwrite_policy),
+ allow_case_insensitive_field_(allow_case_insensitive_field),
+ allow_unknown_field_(allow_unknown_field),
+ allow_unknown_extension_(allow_unknown_extension),
+ allow_unknown_enum_(allow_unknown_enum),
+ allow_field_number_(allow_field_number),
+ allow_partial_(allow_partial),
+ recursion_limit_(recursion_limit),
+ had_errors_(false) {
// For backwards-compatibility with proto1, we need to allow the 'f' suffix
// for floats.
tokenizer_.set_allow_f_after_float(true);
@@ -279,7 +281,7 @@
// Consume the starting token.
tokenizer_.Next();
}
- ~ParserImpl() { }
+ ~ParserImpl() {}
// Parses the ASCII representation specified in input and saves the
// information into the output pointer (a Message). Returns
@@ -311,13 +313,11 @@
if (error_collector_ == NULL) {
if (line >= 0) {
GOOGLE_LOG(ERROR) << "Error parsing text-format "
- << root_message_type_->full_name()
- << ": " << (line + 1) << ":"
- << (col + 1) << ": " << message;
+ << root_message_type_->full_name() << ": " << (line + 1)
+ << ":" << (col + 1) << ": " << message;
} else {
GOOGLE_LOG(ERROR) << "Error parsing text-format "
- << root_message_type_->full_name()
- << ": " << message;
+ << root_message_type_->full_name() << ": " << message;
}
} else {
error_collector_->AddError(line, col, message);
@@ -328,13 +328,11 @@
if (error_collector_ == NULL) {
if (line >= 0) {
GOOGLE_LOG(WARNING) << "Warning parsing text-format "
- << root_message_type_->full_name()
- << ": " << (line + 1) << ":"
- << (col + 1) << ": " << message;
+ << root_message_type_->full_name() << ": " << (line + 1)
+ << ":" << (col + 1) << ": " << message;
} else {
GOOGLE_LOG(WARNING) << "Warning parsing text-format "
- << root_message_type_->full_name()
- << ": " << message;
+ << root_message_type_->full_name() << ": " << message;
}
} else {
error_collector_->AddWarning(line, col, message);
@@ -362,7 +360,7 @@
// This method checks to see that the end delimiter at the conclusion of
// the consumption matches the starting delimiter passed in here.
bool ConsumeMessage(Message* message, const string delimiter) {
- while (!LookingAt(">") && !LookingAt("}")) {
+ while (!LookingAt(">") && !LookingAt("}")) {
DO(ConsumeField(message));
}
@@ -424,9 +422,8 @@
return false;
}
}
- reflection->SetString(
- message, any_type_url_field,
- string(prefix + full_type_name));
+ reflection->SetString(message, any_type_url_field,
+ string(prefix + full_type_name));
reflection->SetString(message, any_value_field, serialized_value);
return true;
}
@@ -440,7 +437,8 @@
if (field == NULL) {
if (!allow_unknown_field_ && !allow_unknown_extension_) {
- ReportError("Extension \"" + field_name + "\" is not defined or "
+ ReportError("Extension \"" + field_name +
+ "\" is not defined or "
"is not an extension of \"" +
descriptor->full_name() + "\".");
return false;
@@ -478,8 +476,8 @@
}
}
// Again, special-case group names as described above.
- if (field != NULL && field->type() == FieldDescriptor::TYPE_GROUP
- && field->message_type()->name() != field_name) {
+ if (field != NULL && field->type() == FieldDescriptor::TYPE_GROUP &&
+ field->message_type()->name() != field_name) {
field = NULL;
}
@@ -536,9 +534,13 @@
if (oneof != NULL && reflection->HasOneof(*message, oneof)) {
const FieldDescriptor* other_field =
reflection->GetOneofFieldDescriptor(*message, oneof);
- ReportError("Field \"" + field_name + "\" is specified along with "
- "field \"" + other_field->name() + "\", another member "
- "of oneof \"" + oneof->name() + "\".");
+ ReportError("Field \"" + field_name +
+ "\" is specified along with "
+ "field \"" +
+ other_field->name() +
+ "\", another member "
+ "of oneof \"" +
+ oneof->name() + "\".");
return false;
}
}
@@ -547,11 +549,15 @@
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
// ':' is optional here.
bool consumed_semicolon = TryConsume(":");
- if (consumed_semicolon && field->options().weak() && LookingAtType(io::Tokenizer::TYPE_STRING)) {
+ if (consumed_semicolon && field->options().weak() &&
+ LookingAtType(io::Tokenizer::TYPE_STRING)) {
// we are getting a bytes string for a weak field.
string tmp;
DO(ConsumeString(&tmp));
- reflection->MutableMessage(message, field)->ParseFromString(tmp);
+ MessageFactory* factory =
+ finder_ ? finder_->FindExtensionFactory(field) : nullptr;
+ reflection->MutableMessage(message, field, factory)
+ ->ParseFromString(tmp);
goto label_skip_parsing;
}
} else {
@@ -581,14 +587,14 @@
} else {
DO(ConsumeFieldValue(message, reflection, field));
}
-label_skip_parsing:
+ label_skip_parsing:
// For historical reasons, fields may optionally be separated by commas or
// semicolons.
TryConsume(";") || TryConsume(",");
if (field->options().deprecated()) {
- ReportWarning("text format contains deprecated field \""
- + field_name + "\"");
+ ReportWarning("text format contains deprecated field \"" + field_name +
+ "\"");
}
// If a parse info tree exists, add the location for the parsed
@@ -629,14 +635,12 @@
return true;
}
- bool ConsumeFieldMessage(Message* message,
- const Reflection* reflection,
+ bool ConsumeFieldMessage(Message* message, const Reflection* reflection,
const FieldDescriptor* field) {
- if (--recursion_budget_ < 0) {
+ if (--recursion_limit_ < 0) {
ReportError("Message is too deep");
return false;
}
-
// If the parse information tree is not NULL, create a nested one
// for the nested message.
ParseInfoTree* parent = parse_info_tree_;
@@ -646,14 +650,17 @@
string delimiter;
DO(ConsumeMessageDelimiter(&delimiter));
+ MessageFactory* factory =
+ finder_ ? finder_->FindExtensionFactory(field) : nullptr;
if (field->is_repeated()) {
- DO(ConsumeMessage(reflection->AddMessage(message, field), delimiter));
+ DO(ConsumeMessage(reflection->AddMessage(message, field, factory),
+ delimiter));
} else {
- DO(ConsumeMessage(reflection->MutableMessage(message, field),
+ DO(ConsumeMessage(reflection->MutableMessage(message, field, factory),
delimiter));
}
- ++recursion_budget_;
+ ++recursion_limit_;
// Reset the parse information tree.
parse_info_tree_ = parent;
@@ -665,28 +672,26 @@
bool SkipFieldMessage() {
string delimiter;
DO(ConsumeMessageDelimiter(&delimiter));
- while (!LookingAt(">") && !LookingAt("}")) {
+ while (!LookingAt(">") && !LookingAt("}")) {
DO(SkipField());
}
DO(Consume(delimiter));
return true;
}
- bool ConsumeFieldValue(Message* message,
- const Reflection* reflection,
+ bool ConsumeFieldValue(Message* message, const Reflection* reflection,
const FieldDescriptor* field) {
-
// Define an easy to use macro for setting fields. This macro checks
// to see if the field is repeated (in which case we need to use the Add
// methods or not (in which case we need to use the Set methods).
-#define SET_FIELD(CPPTYPE, VALUE) \
- if (field->is_repeated()) { \
- reflection->Add##CPPTYPE(message, field, VALUE); \
- } else { \
- reflection->Set##CPPTYPE(message, field, VALUE); \
- } \
+#define SET_FIELD(CPPTYPE, VALUE) \
+ if (field->is_repeated()) { \
+ reflection->Add##CPPTYPE(message, field, VALUE); \
+ } else { \
+ reflection->Set##CPPTYPE(message, field, VALUE); \
+ }
- switch(field->cpp_type()) {
+ switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_INT32: {
int64 value;
DO(ConsumeSignedInteger(&value, kint32max));
@@ -749,8 +754,8 @@
} else if (value == "false" || value == "False" || value == "f") {
SET_FIELD(Bool, false);
} else {
- ReportError("Invalid value for boolean field \"" + field->name()
- + "\". Value: \"" + value + "\".");
+ ReportError("Invalid value for boolean field \"" + field->name() +
+ "\". Value: \"" + value + "\".");
return false;
}
}
@@ -785,12 +790,16 @@
SET_FIELD(EnumValue, int_value);
return true;
} else if (!allow_unknown_enum_) {
- ReportError("Unknown enumeration value of \"" + value + "\" for "
- "field \"" + field->name() + "\".");
+ ReportError("Unknown enumeration value of \"" + value +
+ "\" for "
+ "field \"" +
+ field->name() + "\".");
return false;
} else {
- ReportWarning("Unknown enumeration value of \"" + value + "\" for "
- "field \"" + field->name() + "\".");
+ ReportWarning("Unknown enumeration value of \"" + value +
+ "\" for "
+ "field \"" +
+ field->name() + "\".");
return true;
}
}
@@ -870,8 +879,7 @@
string text = tokenizer_.current().text;
LowerString(&text);
if (text != "inf" &&
- text != "infinity" &&
- text != "nan") {
+ text != "infinity" && text != "nan") {
ReportError("Invalid float number: " + text);
return false;
}
@@ -960,8 +968,8 @@
return false;
}
- if (!io::Tokenizer::ParseInteger(tokenizer_.current().text,
- max_value, value)) {
+ if (!io::Tokenizer::ParseInteger(tokenizer_.current().text, max_value,
+ value)) {
ReportError("Integer out of range (" + tokenizer_.current().text + ")");
return false;
}
@@ -1130,8 +1138,8 @@
const string& current_value = tokenizer_.current().text;
if (current_value != value) {
- ReportError("Expected \"" + value + "\", found \"" + current_value
- + "\".");
+ ReportError("Expected \"" + value + "\", found \"" + current_value +
+ "\".");
return false;
}
@@ -1155,8 +1163,8 @@
// collect any base-level parse errors and feed them to the ParserImpl.
class ParserErrorCollector : public io::ErrorCollector {
public:
- explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) :
- parser_(parser) { }
+ explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser)
+ : parser_(parser) {}
~ParserErrorCollector() override {}
@@ -1186,7 +1194,7 @@
const bool allow_unknown_enum_;
const bool allow_field_number_;
const bool allow_partial_;
- int recursion_budget_;
+ int recursion_limit_;
bool had_errors_;
};
@@ -1198,14 +1206,13 @@
public:
explicit TextGenerator(io::ZeroCopyOutputStream* output,
int initial_indent_level)
- : output_(output),
- buffer_(NULL),
- buffer_size_(0),
- at_start_of_line_(true),
- failed_(false),
- indent_level_(initial_indent_level),
- initial_indent_level_(initial_indent_level) {
- }
+ : output_(output),
+ buffer_(NULL),
+ buffer_size_(0),
+ at_start_of_line_(true),
+ failed_(false),
+ indent_level_(initial_indent_level),
+ initial_indent_level_(initial_indent_level) {}
~TextGenerator() {
// Only BackUp() if we're sure we've successfully called Next() at least
@@ -1223,8 +1230,7 @@
// Reduces the current indent level by two spaces, or crashes if the indent
// level is zero.
void Outdent() override {
- if (indent_level_ == 0 ||
- indent_level_ < initial_indent_level_) {
+ if (indent_level_ == 0 || indent_level_ < initial_indent_level_) {
GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent().";
return;
}
@@ -1298,7 +1304,9 @@
}
void WriteIndent() {
- if (indent_level_ == 0) { return; }
+ if (indent_level_ == 0) {
+ return;
+ }
GOOGLE_DCHECK(!failed_);
int size = 2 * indent_level_;
@@ -1331,8 +1339,7 @@
// ===========================================================================
// Implementation of the default Finder for extensions.
-TextFormat::Finder::~Finder() {
-}
+TextFormat::Finder::~Finder() {}
const FieldDescriptor* TextFormat::Finder::FindExtension(
Message* message, const string& name) const {
@@ -1345,21 +1352,26 @@
return DefaultFinderFindAnyType(message, prefix, name);
}
+MessageFactory* TextFormat::Finder::FindExtensionFactory(
+ const FieldDescriptor* field) const {
+ return nullptr;
+}
+
// ===========================================================================
TextFormat::Parser::Parser()
- : error_collector_(NULL),
- finder_(NULL),
- parse_info_tree_(NULL),
- allow_partial_(false),
- allow_case_insensitive_field_(false),
- allow_unknown_field_(false),
- allow_unknown_extension_(false),
- allow_unknown_enum_(false),
- allow_field_number_(false),
- allow_relaxed_whitespace_(false),
- allow_singular_overwrites_(false) {
-}
+ : error_collector_(NULL),
+ finder_(NULL),
+ parse_info_tree_(NULL),
+ allow_partial_(false),
+ allow_case_insensitive_field_(false),
+ allow_unknown_field_(false),
+ allow_unknown_extension_(false),
+ allow_unknown_enum_(false),
+ allow_field_number_(false),
+ allow_relaxed_whitespace_(false),
+ allow_singular_overwrites_(false),
+ recursion_limit_(std::numeric_limits<int>::max()) {}
TextFormat::Parser::~Parser() {}
@@ -1384,20 +1396,19 @@
output->Clear();
ParserImpl::SingularOverwritePolicy overwrites_policy =
- allow_singular_overwrites_
- ? ParserImpl::ALLOW_SINGULAR_OVERWRITES
- : ParserImpl::FORBID_SINGULAR_OVERWRITES;
+ allow_singular_overwrites_ ? ParserImpl::ALLOW_SINGULAR_OVERWRITES
+ : ParserImpl::FORBID_SINGULAR_OVERWRITES;
- ParserImpl parser(
- output->GetDescriptor(), input, error_collector_, finder_,
- parse_info_tree_, overwrites_policy, allow_case_insensitive_field_,
- allow_unknown_field_, allow_unknown_extension_, allow_unknown_enum_,
- allow_field_number_, allow_relaxed_whitespace_, allow_partial_);
+ ParserImpl parser(output->GetDescriptor(), input, error_collector_, finder_,
+ parse_info_tree_, overwrites_policy,
+ allow_case_insensitive_field_, allow_unknown_field_,
+ allow_unknown_extension_, allow_unknown_enum_,
+ allow_field_number_, allow_relaxed_whitespace_,
+ allow_partial_, recursion_limit_);
return MergeUsingImpl(input, output, &parser);
}
-bool TextFormat::Parser::ParseFromString(const string& input,
- Message* output) {
+bool TextFormat::Parser::ParseFromString(const string& input, Message* output) {
DO(CheckParseInputSize(input, error_collector_));
io::ArrayInputStream input_stream(input.data(), input.size());
return Parse(&input_stream, output);
@@ -1411,12 +1422,11 @@
allow_case_insensitive_field_, allow_unknown_field_,
allow_unknown_extension_, allow_unknown_enum_,
allow_field_number_, allow_relaxed_whitespace_,
- allow_partial_);
+ allow_partial_, recursion_limit_);
return MergeUsingImpl(input, output, &parser);
}
-bool TextFormat::Parser::MergeFromString(const string& input,
- Message* output) {
+bool TextFormat::Parser::MergeFromString(const string& input, Message* output) {
DO(CheckParseInputSize(input, error_collector_));
io::ArrayInputStream input_stream(input.data(), input.size());
return Merge(&input_stream, output);
@@ -1438,17 +1448,16 @@
return true;
}
-bool TextFormat::Parser::ParseFieldValueFromString(
- const string& input,
- const FieldDescriptor* field,
- Message* output) {
+bool TextFormat::Parser::ParseFieldValueFromString(const string& input,
+ const FieldDescriptor* field,
+ Message* output) {
io::ArrayInputStream input_stream(input.data(), input.size());
ParserImpl parser(
output->GetDescriptor(), &input_stream, error_collector_, finder_,
parse_info_tree_, ParserImpl::ALLOW_SINGULAR_OVERWRITES,
allow_case_insensitive_field_, allow_unknown_field_,
allow_unknown_extension_, allow_unknown_enum_, allow_field_number_,
- allow_relaxed_whitespace_, allow_partial_);
+ allow_relaxed_whitespace_, allow_partial_, recursion_limit_);
return parser.ParseField(field, output);
}
@@ -1490,7 +1499,7 @@
// Some compilers do not support ref-qualifiers even in C++11 mode.
// Disable the optimization for now and revisit it later.
-#if 0 // LANG_CXX11
+#if 0 // LANG_CXX11
string Consume() && { return std::move(output_); }
#else // !LANG_CXX11
const string& Get() { return output_; }
@@ -1508,7 +1517,7 @@
TextFormat::FieldValuePrinter::FieldValuePrinter() {}
TextFormat::FieldValuePrinter::~FieldValuePrinter() {}
-#if 0 // LANG_CXX11
+#if 0 // LANG_CXX11
#define FORWARD_IMPL(fn, ...) \
StringBaseTextGenerator generator; \
delegate_.fn(__VA_ARGS__, &generator); \
@@ -1552,23 +1561,18 @@
FORWARD_IMPL(PrintEnum, val, name);
}
string TextFormat::FieldValuePrinter::PrintFieldName(
- const Message& message,
- const Reflection* reflection,
+ const Message& message, const Reflection* reflection,
const FieldDescriptor* field) const {
FORWARD_IMPL(PrintFieldName, message, reflection, field);
}
string TextFormat::FieldValuePrinter::PrintMessageStart(
- const Message& message,
- int field_index,
- int field_count,
+ const Message& message, int field_index, int field_count,
bool single_line_mode) const {
FORWARD_IMPL(PrintMessageStart, message, field_index, field_count,
single_line_mode);
}
string TextFormat::FieldValuePrinter::PrintMessageEnd(
- const Message& message,
- int field_index,
- int field_count,
+ const Message& message, int field_index, int field_count,
bool single_line_mode) const {
FORWARD_IMPL(PrintMessageEnd, message, field_index, field_count,
single_line_mode);
@@ -1775,15 +1779,15 @@
} // namespace
TextFormat::Printer::Printer()
- : initial_indent_level_(0),
- single_line_mode_(false),
- use_field_number_(false),
- use_short_repeated_primitives_(false),
- hide_unknown_fields_(false),
- print_message_fields_in_index_order_(false),
- expand_any_(false),
- truncate_string_field_longer_than_(0LL),
- finder_(NULL) {
+ : initial_indent_level_(0),
+ single_line_mode_(false),
+ use_field_number_(false),
+ use_short_repeated_primitives_(false),
+ hide_unknown_fields_(false),
+ print_message_fields_in_index_order_(false),
+ expand_any_(false),
+ truncate_string_field_longer_than_(0LL),
+ finder_(NULL) {
SetUseUtf8StringEscaping(false);
}
@@ -1808,8 +1812,7 @@
}
bool TextFormat::Printer::RegisterFieldValuePrinter(
- const FieldDescriptor* field,
- const FieldValuePrinter* printer) {
+ const FieldDescriptor* field, const FieldValuePrinter* printer) {
if (field == NULL || printer == NULL) {
return false;
}
@@ -1848,8 +1851,7 @@
}
bool TextFormat::Printer::PrintUnknownFieldsToString(
- const UnknownFieldSet& unknown_fields,
- string* output) const {
+ const UnknownFieldSet& unknown_fields, string* output) const {
GOOGLE_DCHECK(output) << "output specified is NULL";
output->clear();
@@ -1948,13 +1950,25 @@
void TextFormat::Printer::Print(const Message& message,
TextGenerator* generator) const {
+ const Reflection* reflection = message.GetReflection();
+ if (!reflection) {
+ // This message does not provide any way to describe its structure.
+ // Parse it again in an UnknownFieldSet, and display this instead.
+ UnknownFieldSet unknown_fields;
+ {
+ string serialized = message.SerializeAsString();
+ io::ArrayInputStream input(serialized.data(), serialized.size());
+ unknown_fields.ParseFromZeroCopyStream(&input);
+ }
+ PrintUnknownFields(unknown_fields, generator);
+ return;
+ }
const Descriptor* descriptor = message.GetDescriptor();
auto itr = custom_message_printers_.find(descriptor);
if (itr != custom_message_printers_.end()) {
itr->second->Print(message, single_line_mode_, generator);
return;
}
- const Reflection* reflection = message.GetReflection();
if (descriptor->full_name() == internal::kAnyFullTypeName && expand_any_ &&
PrintAny(message, generator)) {
return;
@@ -1978,11 +1992,10 @@
}
}
-void TextFormat::Printer::PrintFieldValueToString(
- const Message& message,
- const FieldDescriptor* field,
- int index,
- string* output) const {
+void TextFormat::Printer::PrintFieldValueToString(const Message& message,
+ const FieldDescriptor* field,
+ int index,
+ string* output) const {
GOOGLE_DCHECK(output) << "output specified is NULL";
output->clear();
@@ -2001,34 +2014,34 @@
const Reflection* reflection = a->GetReflection();
switch (field_->cpp_type()) {
case FieldDescriptor::CPPTYPE_BOOL: {
- bool first = reflection->GetBool(*a, field_);
- bool second = reflection->GetBool(*b, field_);
- return first < second;
+ bool first = reflection->GetBool(*a, field_);
+ bool second = reflection->GetBool(*b, field_);
+ return first < second;
}
case FieldDescriptor::CPPTYPE_INT32: {
- int32 first = reflection->GetInt32(*a, field_);
- int32 second = reflection->GetInt32(*b, field_);
- return first < second;
+ int32 first = reflection->GetInt32(*a, field_);
+ int32 second = reflection->GetInt32(*b, field_);
+ return first < second;
}
case FieldDescriptor::CPPTYPE_INT64: {
- int64 first = reflection->GetInt64(*a, field_);
- int64 second = reflection->GetInt64(*b, field_);
- return first < second;
+ int64 first = reflection->GetInt64(*a, field_);
+ int64 second = reflection->GetInt64(*b, field_);
+ return first < second;
}
case FieldDescriptor::CPPTYPE_UINT32: {
- uint32 first = reflection->GetUInt32(*a, field_);
- uint32 second = reflection->GetUInt32(*b, field_);
- return first < second;
+ uint32 first = reflection->GetUInt32(*a, field_);
+ uint32 second = reflection->GetUInt32(*b, field_);
+ return first < second;
}
case FieldDescriptor::CPPTYPE_UINT64: {
- uint64 first = reflection->GetUInt64(*a, field_);
- uint64 second = reflection->GetUInt64(*b, field_);
- return first < second;
+ uint64 first = reflection->GetUInt64(*a, field_);
+ uint64 second = reflection->GetUInt64(*b, field_);
+ return first < second;
}
case FieldDescriptor::CPPTYPE_STRING: {
- string first = reflection->GetString(*a, field_);
- string second = reflection->GetString(*b, field_);
- return first < second;
+ string first = reflection->GetString(*a, field_);
+ string second = reflection->GetString(*b, field_);
+ return first < second;
}
default:
GOOGLE_LOG(DFATAL) << "Invalid key for map field.";
@@ -2060,8 +2073,7 @@
const FieldDescriptor* field, MessageFactory* factory,
std::vector<const Message*>* sorted_map_field) {
bool need_release = false;
- const MapFieldBase& base =
- *reflection->GetMapData(message, field);
+ const MapFieldBase& base = *reflection->GetMapData(message, field);
if (base.IsRepeatedFieldValid()) {
const RepeatedPtrField<Message>& map_field =
@@ -2171,8 +2183,7 @@
const Reflection* reflection,
const FieldDescriptor* field,
TextGenerator* generator) const {
- if (use_short_repeated_primitives_ &&
- field->is_repeated() &&
+ if (use_short_repeated_primitives_ && field->is_repeated() &&
field->cpp_type() != FieldDescriptor::CPPTYPE_STRING &&
field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
PrintShortRepeatedField(message, reflection, field, generator);
@@ -2294,21 +2305,22 @@
generator); \
break
- OUTPUT_FIELD( INT32, Int32);
- OUTPUT_FIELD( INT64, Int64);
+ OUTPUT_FIELD(INT32, Int32);
+ OUTPUT_FIELD(INT64, Int64);
OUTPUT_FIELD(UINT32, UInt32);
OUTPUT_FIELD(UINT64, UInt64);
- OUTPUT_FIELD( FLOAT, Float);
+ OUTPUT_FIELD(FLOAT, Float);
OUTPUT_FIELD(DOUBLE, Double);
- OUTPUT_FIELD( BOOL, Bool);
+ OUTPUT_FIELD(BOOL, Bool);
#undef OUTPUT_FIELD
case FieldDescriptor::CPPTYPE_STRING: {
string scratch;
- const string& value = field->is_repeated()
- ? reflection->GetRepeatedStringReference(
- message, field, index, &scratch)
- : reflection->GetStringReference(message, field, &scratch);
+ const string& value =
+ field->is_repeated()
+ ? reflection->GetRepeatedStringReference(message, field, index,
+ &scratch)
+ : reflection->GetStringReference(message, field, &scratch);
const string* value_to_print = &value;
string truncated_value;
if (truncate_string_field_longer_than_ > 0 &&
@@ -2327,9 +2339,10 @@
}
case FieldDescriptor::CPPTYPE_ENUM: {
- int enum_value = field->is_repeated()
- ? reflection->GetRepeatedEnumValue(message, field, index)
- : reflection->GetEnumValue(message, field);
+ int enum_value =
+ field->is_repeated()
+ ? reflection->GetRepeatedEnumValue(message, field, index)
+ : reflection->GetEnumValue(message, field);
const EnumValueDescriptor* enum_desc =
field->enum_type()->FindValueByNumber(enum_value);
if (enum_desc != NULL) {
@@ -2349,8 +2362,8 @@
case FieldDescriptor::CPPTYPE_MESSAGE:
Print(field->is_repeated()
- ? reflection->GetRepeatedMessage(message, field, index)
- : reflection->GetMessage(message, field),
+ ? reflection->GetRepeatedMessage(message, field, index)
+ : reflection->GetMessage(message, field),
generator);
break;
}
@@ -2362,13 +2375,12 @@
}
/* static */ bool TextFormat::PrintUnknownFields(
- const UnknownFieldSet& unknown_fields,
- io::ZeroCopyOutputStream* output) {
+ const UnknownFieldSet& unknown_fields, io::ZeroCopyOutputStream* output) {
return Printer().PrintUnknownFields(unknown_fields, output);
}
-/* static */ bool TextFormat::PrintToString(
- const Message& message, string* output) {
+/* static */ bool TextFormat::PrintToString(const Message& message,
+ string* output) {
return Printer().PrintToString(message, output);
}
@@ -2378,28 +2390,24 @@
}
/* static */ void TextFormat::PrintFieldValueToString(
- const Message& message,
- const FieldDescriptor* field,
- int index,
+ const Message& message, const FieldDescriptor* field, int index,
string* output) {
return Printer().PrintFieldValueToString(message, field, index, output);
}
/* static */ bool TextFormat::ParseFieldValueFromString(
- const string& input,
- const FieldDescriptor* field,
- Message* message) {
+ const string& input, const FieldDescriptor* field, Message* message) {
return Parser().ParseFieldValueFromString(input, field, message);
}
// Prints an integer as hex with a fixed number of digits dependent on the
// integer type.
-template<typename IntType>
+template <typename IntType>
static string PaddedHex(IntType value) {
string result;
result.reserve(sizeof(value) * 2);
for (int i = sizeof(value) * 2 - 1; i >= 0; i--) {
- result.push_back(int_to_hex_digit(value >> (i*4) & 0x0F));
+ result.push_back(int_to_hex_digit(value >> (i * 4) & 0x0F));
}
return result;
}
diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h
index d185bfd..3026def 100644
--- a/src/google/protobuf/text_format.h
+++ b/src/google/protobuf/text_format.h
@@ -59,7 +59,7 @@
namespace protobuf {
namespace io {
- class ErrorCollector; // tokenizer.h
+class ErrorCollector; // tokenizer.h
}
// This class implements protocol buffer text format. Printing and parsing
@@ -94,8 +94,7 @@
// be supplied. Note that this method will print the default value for a
// field if it is not set.
static void PrintFieldValueToString(const Message& message,
- const FieldDescriptor* field,
- int index,
+ const FieldDescriptor* field, int index,
std::string* output);
class PROTOBUF_EXPORT BaseTextGenerator {
@@ -174,12 +173,10 @@
virtual std::string PrintFieldName(const Message& message,
const Reflection* reflection,
const FieldDescriptor* field) const;
- virtual std::string PrintMessageStart(const Message& message,
- int field_index,
+ virtual std::string PrintMessageStart(const Message& message, int field_index,
int field_count,
bool single_line_mode) const;
- virtual std::string PrintMessageEnd(const Message& message,
- int field_index,
+ virtual std::string PrintMessageEnd(const Message& message, int field_index,
int field_count,
bool single_line_mode) const;
@@ -208,9 +205,8 @@
// Try to find an extension of *message by fully-qualified field
// name. Returns NULL if no extension is known for this name or number.
// The base implementation uses the extensions already known by the message.
- virtual const FieldDescriptor* FindExtension(
- Message* message,
- const std::string& name) const;
+ virtual const FieldDescriptor* FindExtension(Message* message,
+ const std::string& name) const;
// Find the message type for an Any proto.
// Returns NULL if no message is known for this name.
@@ -220,6 +216,12 @@
virtual const Descriptor* FindAnyType(const Message& message,
const std::string& prefix,
const std::string& name) const;
+
+ // Find the message factory for the given extension field. This can be used
+ // to generalize the Parser to add extension fields to a message in the same
+ // way as the "input" message for the Parser.
+ virtual MessageFactory* FindExtensionFactory(
+ const FieldDescriptor* field) const;
};
// Class for those users which require more fine-grained control over how
@@ -241,8 +243,7 @@
std::string* output) const;
// Like TextFormat::PrintFieldValueToString
void PrintFieldValueToString(const Message& message,
- const FieldDescriptor* field,
- int index,
+ const FieldDescriptor* field, int index,
std::string* output) const;
// Adjust the initial indent level of all output. Each indent level is
@@ -257,9 +258,7 @@
single_line_mode_ = single_line_mode;
}
- bool IsInSingleLineMode() const {
- return single_line_mode_;
- }
+ bool IsInSingleLineMode() const { return single_line_mode_; }
// If use_field_number is true, uses field number instead of field name.
void SetUseFieldNumber(bool use_field_number) {
@@ -293,9 +292,7 @@
// is useful to be able to print the message without unknown fields (e.g.
// for the python protobuf version to maintain consistency between its pure
// python and c++ implementations).
- void SetHideUnknownFields(bool hide) {
- hide_unknown_fields_ = hide;
- }
+ void SetHideUnknownFields(bool hide) { hide_unknown_fields_ = hide; }
// If print_message_fields_in_index_order is true, fields of a proto message
// will be printed using the order defined in source code instead of the
@@ -315,9 +312,7 @@
// If expand==false, print Any using the default printer. The output will
// look like
// type_url: "<type_url>" value: "serialized_content"
- void SetExpandAny(bool expand) {
- expand_any_ = expand;
- }
+ void SetExpandAny(bool expand) { expand_any_ = expand; }
// Set how parser finds message for Any payloads.
void SetFinder(const Finder* finder) { finder_ = finder; }
@@ -491,13 +486,13 @@
ParseInfoTree* CreateNested(const FieldDescriptor* field);
// Defines the map from the index-th field descriptor to its parse location.
- typedef std::map<const FieldDescriptor*,
- std::vector<ParseLocation> > LocationMap;
+ typedef std::map<const FieldDescriptor*, std::vector<ParseLocation> >
+ LocationMap;
// Defines the map from the index-th field descriptor to the nested parse
// info tree.
- typedef std::map<const FieldDescriptor*,
- std::vector<ParseInfoTree*> > NestedMap;
+ typedef std::map<const FieldDescriptor*, std::vector<ParseInfoTree*> >
+ NestedMap;
LocationMap locations_;
NestedMap nested_;
@@ -533,15 +528,11 @@
// Sets where location information about the parse will be written. If NULL
// (the default), then no location will be written.
- void WriteLocationsTo(ParseInfoTree* tree) {
- parse_info_tree_ = tree;
- }
+ void WriteLocationsTo(ParseInfoTree* tree) { parse_info_tree_ = tree; }
// Normally parsing fails if, after parsing, output->IsInitialized()
// returns false. Call AllowPartialMessage(true) to skip this check.
- void AllowPartialMessage(bool allow) {
- allow_partial_ = allow;
- }
+ void AllowPartialMessage(bool allow) { allow_partial_ = allow; }
// Allow field names to be matched case-insensitively.
// This is not advisable if there are fields that only differ in case, or
@@ -559,14 +550,14 @@
// When an unknown extension is met, parsing will fail if this option is set
// to false (the default). If true, unknown extensions will be ignored and
// a warning message will be generated.
- void AllowUnknownExtension(bool allow) {
- allow_unknown_extension_ = allow;
- }
+ void AllowUnknownExtension(bool allow) { allow_unknown_extension_ = allow; }
- void AllowFieldNumber(bool allow) {
- allow_field_number_ = allow;
- }
+ void AllowFieldNumber(bool allow) { allow_field_number_ = allow; }
+
+ // Sets maximum recursion depth which parser can use. This is effectively
+ // the maximum allowed nesting of proto messages.
+ void SetRecursionLimit(int limit) { recursion_limit_ = limit; }
private:
// Forward declaration of an internal class used to parse text
@@ -575,8 +566,7 @@
// Like TextFormat::Merge(). The provided implementation is used
// to do the parsing.
- bool MergeUsingImpl(io::ZeroCopyInputStream* input,
- Message* output,
+ bool MergeUsingImpl(io::ZeroCopyInputStream* input, Message* output,
ParserImpl* parser_impl);
io::ErrorCollector* error_collector_;
@@ -590,6 +580,7 @@
bool allow_field_number_;
bool allow_relaxed_whitespace_;
bool allow_singular_overwrites_;
+ int recursion_limit_;
};
@@ -613,7 +604,6 @@
info_tree->RecordLocation(field, location);
}
-
inline TextFormat::ParseInfoTree* TextFormat::CreateNested(
ParseInfoTree* info_tree, const FieldDescriptor* field) {
return info_tree->CreateNested(field);
diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc
index 89bb164..023827b 100644
--- a/src/google/protobuf/text_format_unittest.cc
+++ b/src/google/protobuf/text_format_unittest.cc
@@ -1313,24 +1313,24 @@
void ExpectMessage(const string& input, const string& message, int line,
int col, Message* proto, bool expected_result) {
- TextFormat::Parser parser;
MockErrorCollector error_collector;
- parser.RecordErrorsTo(&error_collector);
- EXPECT_EQ(expected_result, parser.ParseFromString(input, proto))
+ parser_.RecordErrorsTo(&error_collector);
+ EXPECT_EQ(expected_result, parser_.ParseFromString(input, proto))
<< input << " -> " << proto->DebugString();
EXPECT_EQ(
StrCat(line) + ":" + StrCat(col) + ": " + message + "\n",
error_collector.text_);
+ parser_.RecordErrorsTo(nullptr);
}
void ExpectSuccessAndTree(const string& input, Message* proto,
TextFormat::ParseInfoTree* info_tree) {
- TextFormat::Parser parser;
MockErrorCollector error_collector;
- parser.RecordErrorsTo(&error_collector);
- parser.WriteLocationsTo(info_tree);
-
- EXPECT_TRUE(parser.ParseFromString(input, proto));
+ parser_.RecordErrorsTo(&error_collector);
+ parser_.WriteLocationsTo(info_tree);
+ EXPECT_TRUE(parser_.ParseFromString(input, proto));
+ parser_.WriteLocationsTo(nullptr);
+ parser_.RecordErrorsTo(nullptr);
}
void ExpectLocation(TextFormat::ParseInfoTree* tree,
@@ -1361,6 +1361,8 @@
AddError(line, column, "WARNING:" + message);
}
};
+
+ TextFormat::Parser parser_;
};
TEST_F(TextFormatParserTest, ParseInfoTreeBuilding) {
@@ -1810,18 +1812,20 @@
"\"deprecated_int32\"", 1, 21, &message, true);
}
-TEST_F(TextFormatParserTest, DeepRecursion) {
+TEST_F(TextFormatParserTest, SetRecursionLimit) {
const char* format = "child: { $0 }";
std::string input;
- for (int i = 0; i < 100; ++i)
- input = strings::Substitute(format, input);
+ for (int i = 0; i < 100; ++i) input = strings::Substitute(format, input);
unittest::NestedTestAllTypes message;
ExpectSuccessAndTree(input, &message, nullptr);
input = strings::Substitute(format, input);
- ExpectMessage(input,
- "Message is too deep", 1, 908, &message, false);
+ parser_.SetRecursionLimit(100);
+ ExpectMessage(input, "Message is too deep", 1, 908, &message, false);
+
+ parser_.SetRecursionLimit(101);
+ ExpectSuccessAndTree(input, &message, nullptr);
}
class TextFormatMessageSetTest : public testing::Test {
diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc
index 6cc150b..7232af8 100644
--- a/src/google/protobuf/timestamp.pb.cc
+++ b/src/google/protobuf/timestamp.pb.cc
@@ -42,9 +42,9 @@
::google::protobuf::internal::InitSCC(&scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto.base);
}
-::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2ftimestamp_2eproto[1];
-constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2ftimestamp_2eproto = nullptr;
-constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2ftimestamp_2eproto = nullptr;
+static ::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2ftimestamp_2eproto[1];
+static constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2ftimestamp_2eproto = nullptr;
+static constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2ftimestamp_2eproto = nullptr;
const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2ftimestamp_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
~0u, // no _has_bits_
@@ -63,7 +63,7 @@
reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Timestamp_default_instance_),
};
-::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2ftimestamp_2eproto = {
+static ::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2ftimestamp_2eproto = {
{}, AddDescriptors_google_2fprotobuf_2ftimestamp_2eproto, "google/protobuf/timestamp.proto", schemas,
file_default_instances, TableStruct_google_2fprotobuf_2ftimestamp_2eproto::offsets,
file_level_metadata_google_2fprotobuf_2ftimestamp_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2ftimestamp_2eproto, file_level_service_descriptors_google_2fprotobuf_2ftimestamp_2eproto,
@@ -77,7 +77,7 @@
"obuf/ptypes/timestamp\370\001\001\242\002\003GPB\252\002\036Google."
"Protobuf.WellKnownTypesb\006proto3"
;
-::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftimestamp_2eproto = {
+static ::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftimestamp_2eproto = {
false, InitDefaults_google_2fprotobuf_2ftimestamp_2eproto,
descriptor_table_protodef_google_2fprotobuf_2ftimestamp_2eproto,
"google/protobuf/timestamp.proto", &assign_descriptors_table_google_2fprotobuf_2ftimestamp_2eproto, 231,
@@ -173,43 +173,36 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* Timestamp::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<Timestamp*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* Timestamp::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// int64 seconds = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
- msg->set_seconds(::google::protobuf::internal::ReadVarint(&ptr));
+ set_seconds(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// int32 nanos = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
- msg->set_nanos(::google::protobuf::internal::ReadVarint(&ptr));
+ set_nanos(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h
index f49ca7a..5cf7d4a 100644
--- a/src/google/protobuf/timestamp.pb.h
+++ b/src/google/protobuf/timestamp.pb.h
@@ -31,6 +31,13 @@
#include <google/protobuf/repeated_field.h> // IWYU pragma: export
#include <google/protobuf/extension_set.h> // IWYU pragma: export
#include <google/protobuf/unknown_field_set.h>
+namespace google {
+namespace protobuf {
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+} // namespace protobuf
+} // namespace google
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftimestamp_2eproto PROTOBUF_EXPORT
@@ -131,8 +138,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -144,10 +150,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Timestamp* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.Timestamp";
+ }
protected:
explicit Timestamp(::google::protobuf::Arena* arena);
private:
diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc
index bc31823..26deb9d 100644
--- a/src/google/protobuf/type.pb.cc
+++ b/src/google/protobuf/type.pb.cc
@@ -132,9 +132,9 @@
::google::protobuf::internal::InitSCC(&scc_info_Option_google_2fprotobuf_2ftype_2eproto.base);
}
-::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2ftype_2eproto[5];
-const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[3];
-constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2ftype_2eproto = nullptr;
+static ::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2ftype_2eproto[5];
+static const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[3];
+static constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2ftype_2eproto = nullptr;
const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2ftype_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
~0u, // no _has_bits_
@@ -205,7 +205,7 @@
reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Option_default_instance_),
};
-::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2ftype_2eproto = {
+static ::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2ftype_2eproto = {
{}, AddDescriptors_google_2fprotobuf_2ftype_2eproto, "google/protobuf/type.proto", schemas,
file_default_instances, TableStruct_google_2fprotobuf_2ftype_2eproto::offsets,
file_level_metadata_google_2fprotobuf_2ftype_2eproto, 5, file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto, file_level_service_descriptors_google_2fprotobuf_2ftype_2eproto,
@@ -253,7 +253,7 @@
"oto/protobuf/ptype;ptype\370\001\001\242\002\003GPB\252\002\036Goog"
"le.Protobuf.WellKnownTypesb\006proto3"
;
-::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftype_2eproto = {
+static ::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftype_2eproto = {
false, InitDefaults_google_2fprotobuf_2ftype_2eproto,
descriptor_table_protodef_google_2fprotobuf_2ftype_2eproto,
"google/protobuf/type.proto", &assign_descriptors_table_google_2fprotobuf_2ftype_2eproto, 1594,
@@ -303,30 +303,30 @@
}
}
-#if !defined(_MSC_VER) || _MSC_VER >= 1900
-const Field_Kind Field::TYPE_UNKNOWN;
-const Field_Kind Field::TYPE_DOUBLE;
-const Field_Kind Field::TYPE_FLOAT;
-const Field_Kind Field::TYPE_INT64;
-const Field_Kind Field::TYPE_UINT64;
-const Field_Kind Field::TYPE_INT32;
-const Field_Kind Field::TYPE_FIXED64;
-const Field_Kind Field::TYPE_FIXED32;
-const Field_Kind Field::TYPE_BOOL;
-const Field_Kind Field::TYPE_STRING;
-const Field_Kind Field::TYPE_GROUP;
-const Field_Kind Field::TYPE_MESSAGE;
-const Field_Kind Field::TYPE_BYTES;
-const Field_Kind Field::TYPE_UINT32;
-const Field_Kind Field::TYPE_ENUM;
-const Field_Kind Field::TYPE_SFIXED32;
-const Field_Kind Field::TYPE_SFIXED64;
-const Field_Kind Field::TYPE_SINT32;
-const Field_Kind Field::TYPE_SINT64;
-const Field_Kind Field::Kind_MIN;
-const Field_Kind Field::Kind_MAX;
-const int Field::Kind_ARRAYSIZE;
-#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
+#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
+constexpr Field_Kind Field::TYPE_UNKNOWN;
+constexpr Field_Kind Field::TYPE_DOUBLE;
+constexpr Field_Kind Field::TYPE_FLOAT;
+constexpr Field_Kind Field::TYPE_INT64;
+constexpr Field_Kind Field::TYPE_UINT64;
+constexpr Field_Kind Field::TYPE_INT32;
+constexpr Field_Kind Field::TYPE_FIXED64;
+constexpr Field_Kind Field::TYPE_FIXED32;
+constexpr Field_Kind Field::TYPE_BOOL;
+constexpr Field_Kind Field::TYPE_STRING;
+constexpr Field_Kind Field::TYPE_GROUP;
+constexpr Field_Kind Field::TYPE_MESSAGE;
+constexpr Field_Kind Field::TYPE_BYTES;
+constexpr Field_Kind Field::TYPE_UINT32;
+constexpr Field_Kind Field::TYPE_ENUM;
+constexpr Field_Kind Field::TYPE_SFIXED32;
+constexpr Field_Kind Field::TYPE_SFIXED64;
+constexpr Field_Kind Field::TYPE_SINT32;
+constexpr Field_Kind Field::TYPE_SINT64;
+constexpr Field_Kind Field::Kind_MIN;
+constexpr Field_Kind Field::Kind_MAX;
+constexpr int Field::Kind_ARRAYSIZE;
+#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
const ::google::protobuf::EnumDescriptor* Field_Cardinality_descriptor() {
::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_google_2fprotobuf_2ftype_2eproto);
return file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[1];
@@ -343,15 +343,15 @@
}
}
-#if !defined(_MSC_VER) || _MSC_VER >= 1900
-const Field_Cardinality Field::CARDINALITY_UNKNOWN;
-const Field_Cardinality Field::CARDINALITY_OPTIONAL;
-const Field_Cardinality Field::CARDINALITY_REQUIRED;
-const Field_Cardinality Field::CARDINALITY_REPEATED;
-const Field_Cardinality Field::Cardinality_MIN;
-const Field_Cardinality Field::Cardinality_MAX;
-const int Field::Cardinality_ARRAYSIZE;
-#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
+#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
+constexpr Field_Cardinality Field::CARDINALITY_UNKNOWN;
+constexpr Field_Cardinality Field::CARDINALITY_OPTIONAL;
+constexpr Field_Cardinality Field::CARDINALITY_REQUIRED;
+constexpr Field_Cardinality Field::CARDINALITY_REPEATED;
+constexpr Field_Cardinality Field::Cardinality_MIN;
+constexpr Field_Cardinality Field::Cardinality_MAX;
+constexpr int Field::Cardinality_ARRAYSIZE;
+#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
const ::google::protobuf::EnumDescriptor* Syntax_descriptor() {
::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_google_2fprotobuf_2ftype_2eproto);
return file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[2];
@@ -500,128 +500,78 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* Type::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<Type*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* Type::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// string name = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(mutable_name(), ptr, ctx, "google.protobuf.Type.name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.Type.name");
- object = msg->mutable_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// repeated .google.protobuf.Field fields = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_fields(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::Field::_InternalParse;
- object = msg->add_fields();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
break;
}
// repeated string oneofs = 3;
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(add_oneofs(), ptr, ctx, "google.protobuf.Type.oneofs");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.Type.oneofs");
- object = msg->add_oneofs();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
break;
}
// repeated .google.protobuf.Option options = 4;
case 4: {
if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_options(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::Option::_InternalParse;
- object = msg->add_options();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 34 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 34 && (ptr += 1));
break;
}
// .google.protobuf.SourceContext source_context = 5;
case 5: {
if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(mutable_source_context(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::SourceContext::_InternalParse;
- object = msg->mutable_source_context();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
break;
}
// .google.protobuf.Syntax syntax = 6;
case 6: {
if (static_cast<::google::protobuf::uint8>(tag) != 48) goto handle_unusual;
::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
- msg->set_syntax(static_cast<::google::protobuf::Syntax>(val));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ set_syntax(static_cast<::google::protobuf::Syntax>(val));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool Type::MergePartialFromCodedStream(
@@ -1142,84 +1092,60 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* Field::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<Field*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* Field::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// .google.protobuf.Field.Kind kind = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
- msg->set_kind(static_cast<::google::protobuf::Field_Kind>(val));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ set_kind(static_cast<::google::protobuf::Field_Kind>(val));
break;
}
// .google.protobuf.Field.Cardinality cardinality = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
- msg->set_cardinality(static_cast<::google::protobuf::Field_Cardinality>(val));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ set_cardinality(static_cast<::google::protobuf::Field_Cardinality>(val));
break;
}
// int32 number = 3;
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
- msg->set_number(::google::protobuf::internal::ReadVarint(&ptr));
+ set_number(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// string name = 4;
case 4: {
if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(mutable_name(), ptr, ctx, "google.protobuf.Field.name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.Field.name");
- object = msg->mutable_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// string type_url = 6;
case 6: {
if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(mutable_type_url(), ptr, ctx, "google.protobuf.Field.type_url");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.Field.type_url");
- object = msg->mutable_type_url();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// int32 oneof_index = 7;
case 7: {
if (static_cast<::google::protobuf::uint8>(tag) != 56) goto handle_unusual;
- msg->set_oneof_index(::google::protobuf::internal::ReadVarint(&ptr));
+ set_oneof_index(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
// bool packed = 8;
case 8: {
if (static_cast<::google::protobuf::uint8>(tag) != 64) goto handle_unusual;
- msg->set_packed(::google::protobuf::internal::ReadVarint(&ptr));
+ set_packed(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
@@ -1227,72 +1153,40 @@
case 9: {
if (static_cast<::google::protobuf::uint8>(tag) != 74) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_options(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::Option::_InternalParse;
- object = msg->add_options();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 74 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 74 && (ptr += 1));
break;
}
// string json_name = 10;
case 10: {
if (static_cast<::google::protobuf::uint8>(tag) != 82) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(mutable_json_name(), ptr, ctx, "google.protobuf.Field.json_name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.Field.json_name");
- object = msg->mutable_json_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// string default_value = 11;
case 11: {
if (static_cast<::google::protobuf::uint8>(tag) != 90) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(mutable_default_value(), ptr, ctx, "google.protobuf.Field.default_value");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.Field.default_value");
- object = msg->mutable_default_value();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool Field::MergePartialFromCodedStream(
@@ -1977,109 +1871,68 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* Enum::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<Enum*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* Enum::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// string name = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(mutable_name(), ptr, ctx, "google.protobuf.Enum.name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.Enum.name");
- object = msg->mutable_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// repeated .google.protobuf.EnumValue enumvalue = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_enumvalue(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::EnumValue::_InternalParse;
- object = msg->add_enumvalue();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
break;
}
// repeated .google.protobuf.Option options = 3;
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_options(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::Option::_InternalParse;
- object = msg->add_options();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
break;
}
// .google.protobuf.SourceContext source_context = 4;
case 4: {
if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(mutable_source_context(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::SourceContext::_InternalParse;
- object = msg->mutable_source_context();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
break;
}
// .google.protobuf.Syntax syntax = 5;
case 5: {
if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
- msg->set_syntax(static_cast<::google::protobuf::Syntax>(val));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ set_syntax(static_cast<::google::protobuf::Syntax>(val));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool Enum::MergePartialFromCodedStream(
@@ -2517,38 +2370,23 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* EnumValue::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<EnumValue*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* EnumValue::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// string name = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(mutable_name(), ptr, ctx, "google.protobuf.EnumValue.name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.EnumValue.name");
- object = msg->mutable_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// int32 number = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
- msg->set_number(::google::protobuf::internal::ReadVarint(&ptr));
+ set_number(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
@@ -2556,40 +2394,26 @@
case 3: {
if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
do {
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(add_options(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::Option::_InternalParse;
- object = msg->add_options();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
- if (ptr >= end) break;
- } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
+ if (ctx->Done(&ptr)) return ptr;
+ } while ((::google::protobuf::internal::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool EnumValue::MergePartialFromCodedStream(
@@ -2979,69 +2803,40 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* Option::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<Option*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* Option::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// string name = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(mutable_name(), ptr, ctx, "google.protobuf.Option.name");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.Option.name");
- object = msg->mutable_name();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
// .google.protobuf.Any value = 2;
case 2: {
if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ctx->ParseMessage(mutable_value(), ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- parser_till_end = ::google::protobuf::Any::_InternalParse;
- object = msg->mutable_value();
- if (size > end - ptr) goto len_delim_till_end;
- ptr += size;
- GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
- {parser_till_end, object}, ptr - size, ptr));
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool Option::MergePartialFromCodedStream(
diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h
index ce345ba..73828d8 100644
--- a/src/google/protobuf/type.pb.h
+++ b/src/google/protobuf/type.pb.h
@@ -32,6 +32,13 @@
#include <google/protobuf/extension_set.h> // IWYU pragma: export
#include <google/protobuf/generated_enum_reflection.h>
#include <google/protobuf/unknown_field_set.h>
+namespace google {
+namespace protobuf {
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+} // namespace protobuf
+} // namespace google
#include <google/protobuf/any.pb.h>
#include <google/protobuf/source_context.pb.h>
// @@protoc_insertion_point(includes)
@@ -102,9 +109,9 @@
Field_Kind_Field_Kind_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
PROTOBUF_EXPORT bool Field_Kind_IsValid(int value);
-const Field_Kind Field_Kind_Kind_MIN = Field_Kind_TYPE_UNKNOWN;
-const Field_Kind Field_Kind_Kind_MAX = Field_Kind_TYPE_SINT64;
-const int Field_Kind_Kind_ARRAYSIZE = Field_Kind_Kind_MAX + 1;
+constexpr Field_Kind Field_Kind_Kind_MIN = Field_Kind_TYPE_UNKNOWN;
+constexpr Field_Kind Field_Kind_Kind_MAX = Field_Kind_TYPE_SINT64;
+constexpr int Field_Kind_Kind_ARRAYSIZE = Field_Kind_Kind_MAX + 1;
PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* Field_Kind_descriptor();
inline const ::std::string& Field_Kind_Name(Field_Kind value) {
@@ -125,9 +132,9 @@
Field_Cardinality_Field_Cardinality_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
PROTOBUF_EXPORT bool Field_Cardinality_IsValid(int value);
-const Field_Cardinality Field_Cardinality_Cardinality_MIN = Field_Cardinality_CARDINALITY_UNKNOWN;
-const Field_Cardinality Field_Cardinality_Cardinality_MAX = Field_Cardinality_CARDINALITY_REPEATED;
-const int Field_Cardinality_Cardinality_ARRAYSIZE = Field_Cardinality_Cardinality_MAX + 1;
+constexpr Field_Cardinality Field_Cardinality_Cardinality_MIN = Field_Cardinality_CARDINALITY_UNKNOWN;
+constexpr Field_Cardinality Field_Cardinality_Cardinality_MAX = Field_Cardinality_CARDINALITY_REPEATED;
+constexpr int Field_Cardinality_Cardinality_ARRAYSIZE = Field_Cardinality_Cardinality_MAX + 1;
PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* Field_Cardinality_descriptor();
inline const ::std::string& Field_Cardinality_Name(Field_Cardinality value) {
@@ -146,9 +153,9 @@
Syntax_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
PROTOBUF_EXPORT bool Syntax_IsValid(int value);
-const Syntax Syntax_MIN = SYNTAX_PROTO2;
-const Syntax Syntax_MAX = SYNTAX_PROTO3;
-const int Syntax_ARRAYSIZE = Syntax_MAX + 1;
+constexpr Syntax Syntax_MIN = SYNTAX_PROTO2;
+constexpr Syntax Syntax_MAX = SYNTAX_PROTO3;
+constexpr int Syntax_ARRAYSIZE = Syntax_MAX + 1;
PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* Syntax_descriptor();
inline const ::std::string& Syntax_Name(Syntax value) {
@@ -232,8 +239,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -245,10 +251,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Type* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.Type";
+ }
protected:
explicit Type(::google::protobuf::Arena* arena);
private:
@@ -445,8 +455,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -458,10 +467,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Field* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.Field";
+ }
protected:
explicit Field(::google::protobuf::Arena* arena);
private:
@@ -481,52 +494,52 @@
// nested types ----------------------------------------------------
typedef Field_Kind Kind;
- static const Kind TYPE_UNKNOWN =
+ static constexpr Kind TYPE_UNKNOWN =
Field_Kind_TYPE_UNKNOWN;
- static const Kind TYPE_DOUBLE =
+ static constexpr Kind TYPE_DOUBLE =
Field_Kind_TYPE_DOUBLE;
- static const Kind TYPE_FLOAT =
+ static constexpr Kind TYPE_FLOAT =
Field_Kind_TYPE_FLOAT;
- static const Kind TYPE_INT64 =
+ static constexpr Kind TYPE_INT64 =
Field_Kind_TYPE_INT64;
- static const Kind TYPE_UINT64 =
+ static constexpr Kind TYPE_UINT64 =
Field_Kind_TYPE_UINT64;
- static const Kind TYPE_INT32 =
+ static constexpr Kind TYPE_INT32 =
Field_Kind_TYPE_INT32;
- static const Kind TYPE_FIXED64 =
+ static constexpr Kind TYPE_FIXED64 =
Field_Kind_TYPE_FIXED64;
- static const Kind TYPE_FIXED32 =
+ static constexpr Kind TYPE_FIXED32 =
Field_Kind_TYPE_FIXED32;
- static const Kind TYPE_BOOL =
+ static constexpr Kind TYPE_BOOL =
Field_Kind_TYPE_BOOL;
- static const Kind TYPE_STRING =
+ static constexpr Kind TYPE_STRING =
Field_Kind_TYPE_STRING;
- static const Kind TYPE_GROUP =
+ static constexpr Kind TYPE_GROUP =
Field_Kind_TYPE_GROUP;
- static const Kind TYPE_MESSAGE =
+ static constexpr Kind TYPE_MESSAGE =
Field_Kind_TYPE_MESSAGE;
- static const Kind TYPE_BYTES =
+ static constexpr Kind TYPE_BYTES =
Field_Kind_TYPE_BYTES;
- static const Kind TYPE_UINT32 =
+ static constexpr Kind TYPE_UINT32 =
Field_Kind_TYPE_UINT32;
- static const Kind TYPE_ENUM =
+ static constexpr Kind TYPE_ENUM =
Field_Kind_TYPE_ENUM;
- static const Kind TYPE_SFIXED32 =
+ static constexpr Kind TYPE_SFIXED32 =
Field_Kind_TYPE_SFIXED32;
- static const Kind TYPE_SFIXED64 =
+ static constexpr Kind TYPE_SFIXED64 =
Field_Kind_TYPE_SFIXED64;
- static const Kind TYPE_SINT32 =
+ static constexpr Kind TYPE_SINT32 =
Field_Kind_TYPE_SINT32;
- static const Kind TYPE_SINT64 =
+ static constexpr Kind TYPE_SINT64 =
Field_Kind_TYPE_SINT64;
static inline bool Kind_IsValid(int value) {
return Field_Kind_IsValid(value);
}
- static const Kind Kind_MIN =
+ static constexpr Kind Kind_MIN =
Field_Kind_Kind_MIN;
- static const Kind Kind_MAX =
+ static constexpr Kind Kind_MAX =
Field_Kind_Kind_MAX;
- static const int Kind_ARRAYSIZE =
+ static constexpr int Kind_ARRAYSIZE =
Field_Kind_Kind_ARRAYSIZE;
static inline const ::google::protobuf::EnumDescriptor*
Kind_descriptor() {
@@ -541,22 +554,22 @@
}
typedef Field_Cardinality Cardinality;
- static const Cardinality CARDINALITY_UNKNOWN =
+ static constexpr Cardinality CARDINALITY_UNKNOWN =
Field_Cardinality_CARDINALITY_UNKNOWN;
- static const Cardinality CARDINALITY_OPTIONAL =
+ static constexpr Cardinality CARDINALITY_OPTIONAL =
Field_Cardinality_CARDINALITY_OPTIONAL;
- static const Cardinality CARDINALITY_REQUIRED =
+ static constexpr Cardinality CARDINALITY_REQUIRED =
Field_Cardinality_CARDINALITY_REQUIRED;
- static const Cardinality CARDINALITY_REPEATED =
+ static constexpr Cardinality CARDINALITY_REPEATED =
Field_Cardinality_CARDINALITY_REPEATED;
static inline bool Cardinality_IsValid(int value) {
return Field_Cardinality_IsValid(value);
}
- static const Cardinality Cardinality_MIN =
+ static constexpr Cardinality Cardinality_MIN =
Field_Cardinality_Cardinality_MIN;
- static const Cardinality Cardinality_MAX =
+ static constexpr Cardinality Cardinality_MAX =
Field_Cardinality_Cardinality_MAX;
- static const int Cardinality_ARRAYSIZE =
+ static constexpr int Cardinality_ARRAYSIZE =
Field_Cardinality_Cardinality_ARRAYSIZE;
static inline const ::google::protobuf::EnumDescriptor*
Cardinality_descriptor() {
@@ -799,8 +812,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -812,10 +824,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Enum* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.Enum";
+ }
protected:
explicit Enum(::google::protobuf::Arena* arena);
private:
@@ -989,8 +1005,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -1002,10 +1017,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(EnumValue* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.EnumValue";
+ }
protected:
explicit EnumValue(::google::protobuf::Arena* arena);
private:
@@ -1153,8 +1172,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -1166,10 +1184,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Option* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.Option";
+ }
protected:
explicit Option(::google::protobuf::Arena* arena);
private:
diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto
index 4af2b05..4870382 100644
--- a/src/google/protobuf/unittest.proto
+++ b/src/google/protobuf/unittest.proto
@@ -1002,3 +1002,106 @@
optional int32 test_extension_inside_table_extension = 5;
}
+enum VeryLargeEnum {
+ ENUM_LABEL_DEFAULT = 0;
+ ENUM_LABEL_1 = 1;
+ ENUM_LABEL_2 = 2;
+ ENUM_LABEL_3 = 3;
+ ENUM_LABEL_4 = 4;
+ ENUM_LABEL_5 = 5;
+ ENUM_LABEL_6 = 6;
+ ENUM_LABEL_7 = 7;
+ ENUM_LABEL_8 = 8;
+ ENUM_LABEL_9 = 9;
+ ENUM_LABEL_10 = 10;
+ ENUM_LABEL_11 = 11;
+ ENUM_LABEL_12 = 12;
+ ENUM_LABEL_13 = 13;
+ ENUM_LABEL_14 = 14;
+ ENUM_LABEL_15 = 15;
+ ENUM_LABEL_16 = 16;
+ ENUM_LABEL_17 = 17;
+ ENUM_LABEL_18 = 18;
+ ENUM_LABEL_19 = 19;
+ ENUM_LABEL_20 = 20;
+ ENUM_LABEL_21 = 21;
+ ENUM_LABEL_22 = 22;
+ ENUM_LABEL_23 = 23;
+ ENUM_LABEL_24 = 24;
+ ENUM_LABEL_25 = 25;
+ ENUM_LABEL_26 = 26;
+ ENUM_LABEL_27 = 27;
+ ENUM_LABEL_28 = 28;
+ ENUM_LABEL_29 = 29;
+ ENUM_LABEL_30 = 30;
+ ENUM_LABEL_31 = 31;
+ ENUM_LABEL_32 = 32;
+ ENUM_LABEL_33 = 33;
+ ENUM_LABEL_34 = 34;
+ ENUM_LABEL_35 = 35;
+ ENUM_LABEL_36 = 36;
+ ENUM_LABEL_37 = 37;
+ ENUM_LABEL_38 = 38;
+ ENUM_LABEL_39 = 39;
+ ENUM_LABEL_40 = 40;
+ ENUM_LABEL_41 = 41;
+ ENUM_LABEL_42 = 42;
+ ENUM_LABEL_43 = 43;
+ ENUM_LABEL_44 = 44;
+ ENUM_LABEL_45 = 45;
+ ENUM_LABEL_46 = 46;
+ ENUM_LABEL_47 = 47;
+ ENUM_LABEL_48 = 48;
+ ENUM_LABEL_49 = 49;
+ ENUM_LABEL_50 = 50;
+ ENUM_LABEL_51 = 51;
+ ENUM_LABEL_52 = 52;
+ ENUM_LABEL_53 = 53;
+ ENUM_LABEL_54 = 54;
+ ENUM_LABEL_55 = 55;
+ ENUM_LABEL_56 = 56;
+ ENUM_LABEL_57 = 57;
+ ENUM_LABEL_58 = 58;
+ ENUM_LABEL_59 = 59;
+ ENUM_LABEL_60 = 60;
+ ENUM_LABEL_61 = 61;
+ ENUM_LABEL_62 = 62;
+ ENUM_LABEL_63 = 63;
+ ENUM_LABEL_64 = 64;
+ ENUM_LABEL_65 = 65;
+ ENUM_LABEL_66 = 66;
+ ENUM_LABEL_67 = 67;
+ ENUM_LABEL_68 = 68;
+ ENUM_LABEL_69 = 69;
+ ENUM_LABEL_70 = 70;
+ ENUM_LABEL_71 = 71;
+ ENUM_LABEL_72 = 72;
+ ENUM_LABEL_73 = 73;
+ ENUM_LABEL_74 = 74;
+ ENUM_LABEL_75 = 75;
+ ENUM_LABEL_76 = 76;
+ ENUM_LABEL_77 = 77;
+ ENUM_LABEL_78 = 78;
+ ENUM_LABEL_79 = 79;
+ ENUM_LABEL_80 = 80;
+ ENUM_LABEL_81 = 81;
+ ENUM_LABEL_82 = 82;
+ ENUM_LABEL_83 = 83;
+ ENUM_LABEL_84 = 84;
+ ENUM_LABEL_85 = 85;
+ ENUM_LABEL_86 = 86;
+ ENUM_LABEL_87 = 87;
+ ENUM_LABEL_88 = 88;
+ ENUM_LABEL_89 = 89;
+ ENUM_LABEL_90 = 90;
+ ENUM_LABEL_91 = 91;
+ ENUM_LABEL_92 = 92;
+ ENUM_LABEL_93 = 93;
+ ENUM_LABEL_94 = 94;
+ ENUM_LABEL_95 = 95;
+ ENUM_LABEL_96 = 96;
+ ENUM_LABEL_97 = 97;
+ ENUM_LABEL_98 = 98;
+ ENUM_LABEL_99 = 99;
+ ENUM_LABEL_100 = 100;
+};
diff --git a/src/google/protobuf/unittest_mset.proto b/src/google/protobuf/unittest_mset.proto
index 49d9ada..4e7a8c5 100644
--- a/src/google/protobuf/unittest_mset.proto
+++ b/src/google/protobuf/unittest_mset.proto
@@ -53,6 +53,8 @@
optional TestMessageSetExtension1 message_set_extension = 1545008;
}
optional int32 i = 15;
+ optional proto2_wireformat_unittest.TestMessageSet recursive = 16;
+ optional string test_aliasing = 17 [ctype = STRING_PIECE];
}
message TestMessageSetExtension2 {
diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc
index f0f9ee2..087b6d6 100644
--- a/src/google/protobuf/unknown_field_set.cc
+++ b/src/google/protobuf/unknown_field_set.cc
@@ -36,6 +36,7 @@
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/parse_context.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
@@ -112,9 +113,9 @@
const UnknownField& field = (fields_)[i];
switch (field.type()) {
case UnknownField::TYPE_LENGTH_DELIMITED:
- total_size += sizeof(*field.data_.length_delimited_.string_value_) +
+ total_size += sizeof(*field.data_.length_delimited_.string_value) +
internal::StringSpaceUsedExcludingSelfLong(
- *field.data_.length_delimited_.string_value_);
+ *field.data_.length_delimited_.string_value);
break;
case UnknownField::TYPE_GROUP:
total_size += field.data_.group_->SpaceUsedLong();
@@ -158,9 +159,9 @@
UnknownField field;
field.number_ = number;
field.SetType(UnknownField::TYPE_LENGTH_DELIMITED);
- field.data_.length_delimited_.string_value_ = new string;
+ field.data_.length_delimited_.string_value = new string;
fields_.push_back(field);
- return field.data_.length_delimited_.string_value_;
+ return field.data_.length_delimited_.string_value;
}
@@ -239,7 +240,7 @@
void UnknownField::Delete() {
switch (type()) {
case UnknownField::TYPE_LENGTH_DELIMITED:
- delete data_.length_delimited_.string_value_;
+ delete data_.length_delimited_.string_value;
break;
case UnknownField::TYPE_GROUP:
delete data_.group_;
@@ -252,8 +253,8 @@
void UnknownField::DeepCopy(const UnknownField& other) {
switch (type()) {
case UnknownField::TYPE_LENGTH_DELIMITED:
- data_.length_delimited_.string_value_ = new string(
- *data_.length_delimited_.string_value_);
+ data_.length_delimited_.string_value =
+ new string(*data_.length_delimited_.string_value);
break;
case UnknownField::TYPE_GROUP: {
UnknownFieldSet* group = new UnknownFieldSet();
@@ -270,14 +271,14 @@
void UnknownField::SerializeLengthDelimitedNoTag(
io::CodedOutputStream* output) const {
GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
- const string& data = *data_.length_delimited_.string_value_;
+ const string& data = *data_.length_delimited_.string_value;
output->WriteVarint32(data.size());
output->WriteRawMaybeAliased(data.data(), data.size());
}
uint8* UnknownField::SerializeLengthDelimitedNoTagToArray(uint8* target) const {
GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
- const string& data = *data_.length_delimited_.string_value_;
+ const string& data = *data_.length_delimited_.string_value;
target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target);
target = io::CodedOutputStream::WriteStringToArray(data, target);
return target;
@@ -285,34 +286,50 @@
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
namespace internal {
-
-const char* PackedValidEnumParser(const char* begin, const char* end,
- void* object, ParseContext* ctx) {
+const char* PackedEnumParser(void* object, const char* ptr, ParseContext* ctx,
+ bool (*is_valid)(int), UnknownFieldSet* unknown,
+ int field_num) {
+ int size = ReadSize(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ auto old = ctx->PushLimit(ptr, size);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(old >= 0);
auto repeated_field = static_cast<RepeatedField<int>*>(object);
- auto ptr = begin;
- while (ptr < end) {
+ while (!ctx->DoneNoSlopCheck(&ptr)) {
uint64 varint;
- ptr = io::Parse64(ptr, &varint);
+ ptr = ParseVarint64(ptr, &varint);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
int val = varint;
- if (ctx->extra_parse_data().ValidateEnum<UnknownFieldSet>(val))
+ if (is_valid(val)) {
repeated_field->Add(val);
+ } else {
+ unknown->AddVarint(field_num, val);
+ }
}
+ ctx->PopLimit(old);
return ptr;
}
-
-const char* PackedValidEnumParserArg(const char* begin, const char* end,
- void* object, ParseContext* ctx) {
+const char* PackedEnumParserArg(void* object, const char* ptr,
+ ParseContext* ctx,
+ bool (*is_valid)(const void*, int),
+ const void* data, UnknownFieldSet* unknown,
+ int field_num) {
+ int size = ReadSize(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ auto old = ctx->PushLimit(ptr, size);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(old >= 0);
auto repeated_field = static_cast<RepeatedField<int>*>(object);
- auto ptr = begin;
- while (ptr < end) {
+ while (!ctx->DoneNoSlopCheck(&ptr)) {
uint64 varint;
- ptr = io::Parse64(ptr, &varint);
+ ptr = ParseVarint64(ptr, &varint);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
int val = varint;
- if (ctx->extra_parse_data().ValidateEnumArg<UnknownFieldSet>(val))
+ if (is_valid(data, val)) {
repeated_field->Add(val);
+ } else {
+ unknown->AddVarint(field_num, val);
+ }
}
+ ctx->PopLimit(old);
return ptr;
}
@@ -325,38 +342,39 @@
void AddFixed64(uint32 num, uint64 value) {
unknown_->AddFixed64(num, value);
}
- ParseClosure AddLengthDelimited(uint32 num, uint32 size) {
+ const char* ParseLengthDelimited(uint32 num, const char* ptr,
+ ParseContext* ctx) {
string* s = unknown_->AddLengthDelimited(num);
- // TODO(gerbens) SECURITY: add security
- s->reserve(size);
- return {GreedyStringParser, s};
+ int size = ReadSize(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ return ctx->ReadString(ptr, size, s);
}
- ParseClosure StartGroup(uint32 num) {
- return {UnknownGroupParse, unknown_->AddGroup(num)};
+ const char* ParseGroup(uint32 num, const char* ptr, ParseContext* ctx) {
+ UnknownFieldParserHelper child(unknown_->AddGroup(num));
+ return ctx->ParseGroup(&child, ptr, num * 8 + 3);
}
- void EndGroup(uint32 num) {}
void AddFixed32(uint32 num, uint32 value) {
unknown_->AddFixed32(num, value);
}
+ const char* _InternalParse(const char* ptr, ParseContext* ctx) {
+ return WireFormatParser(*this, ptr, ctx);
+ }
+
private:
UnknownFieldSet* unknown_;
};
-const char* UnknownGroupParse(const char* begin, const char* end, void* object,
+const char* UnknownGroupParse(UnknownFieldSet* unknown, const char* ptr,
ParseContext* ctx) {
- UnknownFieldParserHelper field_parser(static_cast<UnknownFieldSet*>(object));
- return WireFormatParser({UnknownGroupParse, object}, field_parser, begin, end,
- ctx);
+ UnknownFieldParserHelper field_parser(unknown);
+ return WireFormatParser(field_parser, ptr, ctx);
}
-std::pair<const char*, bool> UnknownFieldParse(uint64 tag, ParseClosure parent,
- const char* begin,
- const char* end,
- UnknownFieldSet* unknown,
- ParseContext* ctx) {
+const char* UnknownFieldParse(uint64 tag, UnknownFieldSet* unknown,
+ const char* ptr, ParseContext* ctx) {
UnknownFieldParserHelper field_parser(unknown);
- return FieldParser(tag, parent, field_parser, begin, end, ctx);
+ return FieldParser(tag, field_parser, ptr, ctx);
}
} // namespace internal
diff --git a/src/google/protobuf/unknown_field_set.h b/src/google/protobuf/unknown_field_set.h
index d8335cd..4d1c6df 100644
--- a/src/google/protobuf/unknown_field_set.h
+++ b/src/google/protobuf/unknown_field_set.h
@@ -186,6 +186,7 @@
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
namespace internal {
+
inline void WriteVarint(uint32 num, uint64 val, UnknownFieldSet* unknown) {
unknown->AddVarint(num, val);
}
@@ -195,20 +196,22 @@
}
PROTOBUF_EXPORT
-const char* PackedValidEnumParser(const char* begin, const char* end,
- void* object, ParseContext* ctx);
+const char* PackedEnumParser(void* object, const char* ptr, ParseContext* ctx,
+ bool (*is_valid)(int), UnknownFieldSet* unknown,
+ int field_num);
PROTOBUF_EXPORT
-const char* PackedValidEnumParserArg(const char* begin, const char* end,
- void* object, ParseContext* ctx);
+const char* PackedEnumParserArg(void* object, const char* ptr,
+ ParseContext* ctx,
+ bool (*is_valid)(const void*, int),
+ const void* data, UnknownFieldSet* unknown,
+ int field_num);
+
PROTOBUF_EXPORT
-const char* UnknownGroupParse(const char* begin, const char* end, void* object,
+const char* UnknownGroupParse(UnknownFieldSet* unknown, const char* ptr,
ParseContext* ctx);
PROTOBUF_EXPORT
-std::pair<const char*, bool> UnknownFieldParse(uint64 tag, ParseClosure parent,
- const char* begin,
- const char* end,
- UnknownFieldSet* unknown,
- ParseContext* ctx);
+const char* UnknownFieldParse(uint64 tag, UnknownFieldSet* unknown,
+ const char* ptr, ParseContext* ctx);
} // namespace internal
#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
@@ -267,7 +270,7 @@
inline void SetType(Type type);
union LengthDelimited {
- std::string* string_value_;
+ std::string* string_value;
};
uint32 number_;
@@ -341,7 +344,7 @@
}
inline const std::string& UnknownField::length_delimited() const {
assert(type() == TYPE_LENGTH_DELIMITED);
- return *data_.length_delimited_.string_value_;
+ return *data_.length_delimited_.string_value;
}
inline const UnknownFieldSet& UnknownField::group() const {
assert(type() == TYPE_GROUP);
@@ -362,11 +365,11 @@
}
inline void UnknownField::set_length_delimited(const std::string& value) {
assert(type() == TYPE_LENGTH_DELIMITED);
- data_.length_delimited_.string_value_->assign(value);
+ data_.length_delimited_.string_value->assign(value);
}
inline std::string* UnknownField::mutable_length_delimited() {
assert(type() == TYPE_LENGTH_DELIMITED);
- return data_.length_delimited_.string_value_;
+ return data_.length_delimited_.string_value;
}
inline UnknownFieldSet* UnknownField::mutable_group() {
assert(type() == TYPE_GROUP);
@@ -375,7 +378,7 @@
inline size_t UnknownField::GetLengthDelimitedSize() const {
GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
- return data_.length_delimited_.string_value_->size();
+ return data_.length_delimited_.string_value->size();
}
inline void UnknownField::SetType(Type type) {
diff --git a/src/google/protobuf/util/field_comparator.h b/src/google/protobuf/util/field_comparator.h
index 257f6ab..ca78fc5 100644
--- a/src/google/protobuf/util/field_comparator.h
+++ b/src/google/protobuf/util/field_comparator.h
@@ -182,7 +182,8 @@
// basic types (instead of submessages). They return true on success. One
// can use ResultFromBoolean() to convert that boolean to a ComparisonResult
// value.
- bool CompareBool(const FieldDescriptor& /* unused */, bool value_1, bool value_2) {
+ bool CompareBool(const FieldDescriptor& /* unused */,
+ bool value_1, bool value_2) {
return value_1 == value_2;
}
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter_test.cc b/src/google/protobuf/util/internal/default_value_objectwriter_test.cc
index 0c4af61..2897759 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter_test.cc
+++ b/src/google/protobuf/util/internal/default_value_objectwriter_test.cc
@@ -72,10 +72,10 @@
virtual ~DefaultValueObjectWriterTest() {}
};
-INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- DefaultValueObjectWriterTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ DefaultValueObjectWriterTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
TEST_P(DefaultValueObjectWriterTest, Empty) {
// Set expectation
@@ -159,10 +159,10 @@
~DefaultValueObjectWriterSuppressListTest() override {}
};
-INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- DefaultValueObjectWriterSuppressListTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ DefaultValueObjectWriterSuppressListTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
TEST_P(DefaultValueObjectWriterSuppressListTest, Empty) {
// Set expectation. Emtpy lists should be suppressed.
diff --git a/src/google/protobuf/util/internal/proto_writer.h b/src/google/protobuf/util/internal/proto_writer.h
index b67d76e..e90f6e2 100644
--- a/src/google/protobuf/util/internal/proto_writer.h
+++ b/src/google/protobuf/util/internal/proto_writer.h
@@ -154,6 +154,8 @@
ignore_unknown_fields_ = ignore_unknown_fields;
}
+ bool ignore_unknown_fields() { return ignore_unknown_fields_; }
+
void set_ignore_unknown_enum_values(bool ignore_unknown_enum_values) {
ignore_unknown_enum_values_ = ignore_unknown_enum_values;
}
diff --git a/src/google/protobuf/util/internal/protostream_objectsource_test.cc b/src/google/protobuf/util/internal/protostream_objectsource_test.cc
index 8a8b0c4..f242fa1 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource_test.cc
+++ b/src/google/protobuf/util/internal/protostream_objectsource_test.cc
@@ -290,10 +290,10 @@
bool render_unknown_enum_values_;
};
-INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- ProtostreamObjectSourceTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtostreamObjectSourceTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
TEST_P(ProtostreamObjectSourceTest, EmptyMessage) {
Book empty;
@@ -606,10 +606,10 @@
}
};
-INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- ProtostreamObjectSourceMapsTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtostreamObjectSourceMapsTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
// Tests JSON map.
//
@@ -748,10 +748,10 @@
}
};
-INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- ProtostreamObjectSourceAnysTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtostreamObjectSourceAnysTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
// Tests JSON any support.
//
@@ -984,10 +984,10 @@
}
};
-INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- ProtostreamObjectSourceStructTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtostreamObjectSourceStructTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
// Tests struct
//
@@ -1030,10 +1030,10 @@
}
};
-INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- ProtostreamObjectSourceFieldMaskTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtostreamObjectSourceFieldMaskTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
TEST_P(ProtostreamObjectSourceFieldMaskTest, FieldMaskRenderSuccess) {
FieldMaskTest out;
@@ -1093,10 +1093,10 @@
}
};
-INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- ProtostreamObjectSourceTimestampTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtostreamObjectSourceTimestampTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
TEST_P(ProtostreamObjectSourceTimestampTest, InvalidTimestampBelowMinTest) {
TimestampDuration out;
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
index da24dd5..adedc3b 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
@@ -190,10 +190,10 @@
virtual ~ProtoStreamObjectWriterTest() {}
};
-INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- ProtoStreamObjectWriterTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtoStreamObjectWriterTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
TEST_P(ProtoStreamObjectWriterTest, EmptyObject) {
Book empty;
@@ -1198,10 +1198,10 @@
}
};
-INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- ProtoStreamObjectWriterTimestampDurationTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtoStreamObjectWriterTimestampDurationTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
TEST_P(ProtoStreamObjectWriterTimestampDurationTest, ParseTimestamp) {
TimestampDuration timestamp;
@@ -1594,10 +1594,10 @@
}
};
-INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- ProtoStreamObjectWriterStructTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtoStreamObjectWriterStructTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
// TODO(skarvaje): Write tests for failure cases.
TEST_P(ProtoStreamObjectWriterStructTest, StructRenderSuccess) {
@@ -1746,10 +1746,10 @@
}
};
-INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- ProtoStreamObjectWriterMapTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtoStreamObjectWriterMapTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
TEST_P(ProtoStreamObjectWriterMapTest, MapShouldNotAcceptList) {
MapIn mm;
@@ -1843,10 +1843,10 @@
}
};
-INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- ProtoStreamObjectWriterAnyTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtoStreamObjectWriterAnyTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
TEST_P(ProtoStreamObjectWriterAnyTest, AnyRenderSuccess) {
AnyOut any;
@@ -2484,10 +2484,10 @@
}
};
-INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- ProtoStreamObjectWriterFieldMaskTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtoStreamObjectWriterFieldMaskTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
TEST_P(ProtoStreamObjectWriterFieldMaskTest, SimpleFieldMaskTest) {
FieldMaskTest expected;
@@ -2737,10 +2737,10 @@
}
};
-INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- ProtoStreamObjectWriterWrappersTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtoStreamObjectWriterWrappersTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
TEST_P(ProtoStreamObjectWriterWrappersTest, WrapperAcceptsNull) {
Int32Wrapper wrapper;
@@ -2760,10 +2760,10 @@
}
};
-INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- ProtoStreamObjectWriterOneOfsTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtoStreamObjectWriterOneOfsTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
TEST_P(ProtoStreamObjectWriterOneOfsTest,
MultipleOneofsFailForPrimitiveTypesTest) {
diff --git a/src/google/protobuf/util/json_format.proto b/src/google/protobuf/util/json_format.proto
index 767611f..1120bc1 100644
--- a/src/google/protobuf/util/json_format.proto
+++ b/src/google/protobuf/util/json_format.proto
@@ -111,3 +111,9 @@
message TestStringMap {
map<string, string> string_map = 1;
}
+
+message TestStringSerializer {
+ optional string scalar_string = 1;
+ repeated string repeated_string = 2;
+ map<string, string> string_map = 3;
+}
diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h
index 0f1a03b..f9d33fa 100644
--- a/src/google/protobuf/wire_format_lite.h
+++ b/src/google/protobuf/wire_format_lite.h
@@ -171,7 +171,7 @@
//
// This is different from MakeTag(field->number(), field->type()) in the
// case of packed repeated fields.
- static uint32 MakeTag(int field_number, WireType type);
+ constexpr static uint32 MakeTag(int field_number, WireType type);
static WireType GetTagWireType(uint32 tag);
static int GetTagFieldNumber(uint32 tag);
@@ -650,20 +650,6 @@
uint8* target) {
return InternalWriteMessageToArray(field_number, value, target);
}
- template <typename MessageType>
- INL static uint8* WriteGroupNoVirtualToArray(int field_number,
- const MessageType& value,
- uint8* target) {
- return InternalWriteGroupNoVirtualToArray(field_number, value, false,
- target);
- }
- template <typename MessageType>
- INL static uint8* WriteMessageNoVirtualToArray(int field_number,
- const MessageType& value,
- uint8* target) {
- return InternalWriteMessageNoVirtualToArray(field_number, value, false,
- target);
- }
#undef INL
@@ -784,7 +770,8 @@
return kFieldTypeToCppTypeMap[type];
}
-inline uint32 WireFormatLite::MakeTag(int field_number, WireType type) {
+constexpr inline uint32 WireFormatLite::MakeTag(int field_number,
+ WireType type) {
return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type);
}
@@ -912,29 +899,6 @@
return unknown_fields.size();
}
-// Some convenience functions to simplify the generated parse loop code.
-// Returning the value and updating the buffer pointer allows for nicer
-// function composition. We rely on the compiler to inline this.
-// Also in debug compiles having local scoped variables tend to generated
-// stack frames that scale as O(num fields).
-inline uint64 ReadVarint(const char** p) {
- uint64 tmp;
- *p = io::Parse64(*p, &tmp);
- return tmp;
-}
-
-inline int64 ReadVarintZigZag64(const char** p) {
- uint64 tmp;
- *p = io::Parse64(*p, &tmp);
- return WireFormatLite::ZigZagDecode64(tmp);
-}
-
-inline int32 ReadVarintZigZag32(const char** p) {
- uint64 tmp;
- *p = io::Parse64(*p, &tmp);
- return WireFormatLite::ZigZagDecode32(tmp);
-}
-
} // namespace internal
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/wire_format_lite_inl.h b/src/google/protobuf/wire_format_lite_inl.h
index 266b1e1..15c75a6 100644
--- a/src/google/protobuf/wire_format_lite_inl.h
+++ b/src/google/protobuf/wire_format_lite_inl.h
@@ -1021,6 +1021,7 @@
io::CodedInputStream sub_input(
reinterpret_cast<const uint8*>(message_data.data()),
static_cast<int>(message_data.size()));
+ sub_input.SetRecursionLimit(input->RecursionBudget());
if (!ms.ParseField(last_type_id, &sub_input)) {
return false;
}
diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc
index 114e883..62b5351 100644
--- a/src/google/protobuf/wire_format_unittest.cc
+++ b/src/google/protobuf/wire_format_unittest.cc
@@ -599,8 +599,8 @@
{
// Test parse the message via Reflection.
proto2_wireformat_unittest::TestMessageSet message_set;
- io::CodedInputStream input(
- reinterpret_cast<const uint8*>(data.data()), data.size());
+ io::CodedInputStream input(reinterpret_cast<const uint8*>(data.data()),
+ data.size());
EXPECT_TRUE(WireFormat::ParseAndMergePartial(&input, &message_set));
EXPECT_TRUE(input.ConsumedEntireMessage());
@@ -609,6 +609,65 @@
}
}
+void SerializeReverseOrder(
+ const proto2_wireformat_unittest::TestMessageSet& mset,
+ io::CodedOutputStream* coded_output);
+
+void SerializeReverseOrder(const unittest::TestMessageSetExtension1& message,
+ io::CodedOutputStream* coded_output) {
+ WireFormatLite::WriteTag(15, // i
+ WireFormatLite::WIRETYPE_VARINT, coded_output);
+ coded_output->WriteVarint32(message.i());
+ WireFormatLite::WriteTag(16, // recursive
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+ coded_output);
+ coded_output->WriteVarint32(message.recursive().GetCachedSize());
+ SerializeReverseOrder(message.recursive(), coded_output);
+}
+
+void SerializeReverseOrder(
+ const proto2_wireformat_unittest::TestMessageSet& mset,
+ io::CodedOutputStream* coded_output) {
+ if (!mset.HasExtension(
+ unittest::TestMessageSetExtension1::message_set_extension))
+ return;
+ coded_output->WriteTag(WireFormatLite::kMessageSetItemStartTag);
+ // Write the message content first.
+ WireFormatLite::WriteTag(WireFormatLite::kMessageSetMessageNumber,
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+ coded_output);
+ auto& message = mset.GetExtension(
+ unittest::TestMessageSetExtension1::message_set_extension);
+ coded_output->WriteVarint32(message.GetCachedSize());
+ SerializeReverseOrder(message, coded_output);
+ // Write the type id.
+ uint32 type_id = message.GetDescriptor()->extension(0)->number();
+ WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber, type_id,
+ coded_output);
+ coded_output->WriteTag(WireFormatLite::kMessageSetItemEndTag);
+}
+
+TEST(WireFormatTest, ParseMessageSetWithDeepRecReverseOrder) {
+ string data;
+ {
+ proto2_wireformat_unittest::TestMessageSet message_set;
+ proto2_wireformat_unittest::TestMessageSet* mset = &message_set;
+ for (int i = 0; i < 200; i++) {
+ auto m = mset->MutableExtension(
+ unittest::TestMessageSetExtension1::message_set_extension);
+ m->set_i(i);
+ mset = m->mutable_recursive();
+ }
+ message_set.ByteSizeLong();
+ // Serialize with reverse payload tag order
+ io::StringOutputStream output_stream(&data);
+ io::CodedOutputStream coded_output(&output_stream);
+ SerializeReverseOrder(message_set, &coded_output);
+ }
+ proto2_wireformat_unittest::TestMessageSet message_set;
+ EXPECT_FALSE(message_set.ParseFromString(data));
+}
+
TEST(WireFormatTest, ParseBrokenMessageSet) {
proto2_wireformat_unittest::TestMessageSet message_set;
string input("goodbye"); // Invalid wire format data.
diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc
index 12fd317..b65975f 100644
--- a/src/google/protobuf/wrappers.pb.cc
+++ b/src/google/protobuf/wrappers.pb.cc
@@ -194,9 +194,9 @@
::google::protobuf::internal::InitSCC(&scc_info_BytesValue_google_2fprotobuf_2fwrappers_2eproto.base);
}
-::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[9];
-constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fwrappers_2eproto = nullptr;
-constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fwrappers_2eproto = nullptr;
+static ::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[9];
+static constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fwrappers_2eproto = nullptr;
+static constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fwrappers_2eproto = nullptr;
const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2fwrappers_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
~0u, // no _has_bits_
@@ -278,7 +278,7 @@
reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_BytesValue_default_instance_),
};
-::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fwrappers_2eproto = {
+static ::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fwrappers_2eproto = {
{}, AddDescriptors_google_2fprotobuf_2fwrappers_2eproto, "google/protobuf/wrappers.proto", schemas,
file_default_instances, TableStruct_google_2fprotobuf_2fwrappers_2eproto::offsets,
file_level_metadata_google_2fprotobuf_2fwrappers_2eproto, 9, file_level_enum_descriptors_google_2fprotobuf_2fwrappers_2eproto, file_level_service_descriptors_google_2fprotobuf_2fwrappers_2eproto,
@@ -298,7 +298,7 @@
"\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypesb"
"\006proto3"
;
-::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fwrappers_2eproto = {
+static ::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fwrappers_2eproto = {
false, InitDefaults_google_2fprotobuf_2fwrappers_2eproto,
descriptor_table_protodef_google_2fprotobuf_2fwrappers_2eproto,
"google/protobuf/wrappers.proto", &assign_descriptors_table_google_2fprotobuf_2fwrappers_2eproto, 447,
@@ -387,36 +387,29 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* DoubleValue::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<DoubleValue*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* DoubleValue::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// double value = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 9) goto handle_unusual;
- msg->set_value(::google::protobuf::io::UnalignedLoad<double>(ptr));
+ set_value(::google::protobuf::internal::UnalignedLoad<double>(ptr));
ptr += sizeof(double);
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
@@ -674,36 +667,29 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* FloatValue::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<FloatValue*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* FloatValue::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// float value = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 13) goto handle_unusual;
- msg->set_value(::google::protobuf::io::UnalignedLoad<float>(ptr));
+ set_value(::google::protobuf::internal::UnalignedLoad<float>(ptr));
ptr += sizeof(float);
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
@@ -961,36 +947,29 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* Int64Value::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<Int64Value*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* Int64Value::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// int64 value = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
- msg->set_value(::google::protobuf::internal::ReadVarint(&ptr));
+ set_value(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
@@ -1250,36 +1229,29 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* UInt64Value::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<UInt64Value*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* UInt64Value::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// uint64 value = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
- msg->set_value(::google::protobuf::internal::ReadVarint(&ptr));
+ set_value(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
@@ -1539,36 +1511,29 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* Int32Value::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<Int32Value*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* Int32Value::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// int32 value = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
- msg->set_value(::google::protobuf::internal::ReadVarint(&ptr));
+ set_value(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
@@ -1828,36 +1793,29 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* UInt32Value::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<UInt32Value*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* UInt32Value::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// uint32 value = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
- msg->set_value(::google::protobuf::internal::ReadVarint(&ptr));
+ set_value(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
@@ -2117,36 +2075,29 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* BoolValue::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<BoolValue*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* BoolValue::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// bool value = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
- msg->set_value(::google::protobuf::internal::ReadVarint(&ptr));
+ set_value(::google::protobuf::internal::ReadVarint(&ptr));
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
@@ -2411,56 +2362,33 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* StringValue::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<StringValue*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* StringValue::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// string value = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParserUTF8(mutable_value(), ptr, ctx, "google.protobuf.StringValue.value");
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- ctx->extra_parse_data().SetFieldName("google.protobuf.StringValue.value");
- object = msg->mutable_value();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool StringValue::MergePartialFromCodedStream(
@@ -2737,55 +2665,33 @@
}
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-const char* BytesValue::_InternalParse(const char* begin, const char* end, void* object,
- ::google::protobuf::internal::ParseContext* ctx) {
- auto msg = static_cast<BytesValue*>(object);
- ::google::protobuf::int32 size; (void)size;
- int depth; (void)depth;
- ::google::protobuf::uint32 tag;
- ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
- auto ptr = begin;
- while (ptr < end) {
- ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+const char* BytesValue::_InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) {
+ while (!ctx->Done(&ptr)) {
+ ::google::protobuf::uint32 tag;
+ ptr = ::google::protobuf::internal::ReadTag(ptr, &tag);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
switch (tag >> 3) {
// bytes value = 1;
case 1: {
if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
- ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+ ptr = ::google::protobuf::internal::InlineGreedyStringParser(mutable_value(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- object = msg->mutable_value();
- if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
- parser_till_end = ::google::protobuf::internal::GreedyStringParser;
- goto string_till_end;
- }
- GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheck(ptr, size, ctx));
- ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
- ptr += size;
break;
}
default: {
handle_unusual:
if ((tag & 7) == 4 || tag == 0) {
- ctx->EndGroup(tag);
+ ctx->SetLastTag(tag);
return ptr;
}
- auto res = UnknownFieldParse(tag, {_InternalParse, msg},
- ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
- ptr = res.first;
+ ptr = UnknownFieldParse(tag,
+ _internal_metadata_.mutable_unknown_fields(), ptr, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
- if (res.second) return ptr;
+ break;
}
} // switch
} // while
return ptr;
-string_till_end:
- static_cast<::std::string*>(object)->clear();
- static_cast<::std::string*>(object)->reserve(size);
- goto len_delim_till_end;
-len_delim_till_end:
- return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
- {parser_till_end, object}, size);
}
#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool BytesValue::MergePartialFromCodedStream(
diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h
index 11a7662..420a5b7 100644
--- a/src/google/protobuf/wrappers.pb.h
+++ b/src/google/protobuf/wrappers.pb.h
@@ -31,6 +31,13 @@
#include <google/protobuf/repeated_field.h> // IWYU pragma: export
#include <google/protobuf/extension_set.h> // IWYU pragma: export
#include <google/protobuf/unknown_field_set.h>
+namespace google {
+namespace protobuf {
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+} // namespace protobuf
+} // namespace google
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fwrappers_2eproto PROTOBUF_EXPORT
@@ -163,8 +170,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -176,10 +182,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(DoubleValue* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.DoubleValue";
+ }
protected:
explicit DoubleValue(::google::protobuf::Arena* arena);
private:
@@ -290,8 +300,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -303,10 +312,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(FloatValue* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.FloatValue";
+ }
protected:
explicit FloatValue(::google::protobuf::Arena* arena);
private:
@@ -417,8 +430,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -430,10 +442,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Int64Value* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.Int64Value";
+ }
protected:
explicit Int64Value(::google::protobuf::Arena* arena);
private:
@@ -544,8 +560,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -557,10 +572,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(UInt64Value* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.UInt64Value";
+ }
protected:
explicit UInt64Value(::google::protobuf::Arena* arena);
private:
@@ -671,8 +690,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -684,10 +702,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Int32Value* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.Int32Value";
+ }
protected:
explicit Int32Value(::google::protobuf::Arena* arena);
private:
@@ -798,8 +820,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -811,10 +832,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(UInt32Value* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.UInt32Value";
+ }
protected:
explicit UInt32Value(::google::protobuf::Arena* arena);
private:
@@ -925,8 +950,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -938,10 +962,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(BoolValue* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.BoolValue";
+ }
protected:
explicit BoolValue(::google::protobuf::Arena* arena);
private:
@@ -1052,8 +1080,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -1065,10 +1092,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(StringValue* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.StringValue";
+ }
protected:
explicit StringValue(::google::protobuf::Arena* arena);
private:
@@ -1196,8 +1227,7 @@
size_t ByteSizeLong() const final;
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
- static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
- ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+ const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
#else
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
@@ -1209,10 +1239,14 @@
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
- void SharedCtor();
- void SharedDtor();
+ inline void SharedCtor();
+ inline void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(BytesValue* other);
+ friend class ::google::protobuf::internal::AnyMetadata;
+ static ::google::protobuf::StringPiece FullMessageName() {
+ return "google.protobuf.BytesValue";
+ }
protected:
explicit BytesValue(::google::protobuf::Arena* arena);
private: