diff --git a/java/core/src/main/java/com/google/protobuf/CheckReturnValue.java b/java/core/src/main/java/com/google/protobuf/CheckReturnValue.java
index 38c83d898c..99abc32888 100644
--- a/java/core/src/main/java/com/google/protobuf/CheckReturnValue.java
+++ b/java/core/src/main/java/com/google/protobuf/CheckReturnValue.java
@@ -41,13 +41,13 @@ import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
- * Indicates that the return value of the annotated method must be checked. An error is triggered
- * when one of these methods is called but the result is not used.
+ * Indicates that the return value of the annotated method must be used. An error is triggered when
+ * one of these methods is called but the result is not used.
*
*
{@code @CheckReturnValue} may be applied to a class or package to indicate that all methods in
- * that class or package must have their return values checked. For convenience, we provide an
- * annotation, {@link CanIgnoreReturnValue}, to exempt specific methods or classes from this
- * behavior.
+ * that class (including indirectly; that is, methods of inner classes within the annotated class)
+ * or package must have their return values used. For convenience, we provide an annotation, {@link
+ * CanIgnoreReturnValue}, to exempt specific methods or classes from this behavior.
*/
@Documented
@Target({METHOD, CONSTRUCTOR, TYPE, PACKAGE})
diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
index caa58e1ada..4b2aa07628 100644
--- a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
+++ b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
@@ -123,16 +123,15 @@ public class ExtensionRegistryLite {
* ExtensionRegistry} (if the full (non-Lite) proto libraries are available).
*/
public static ExtensionRegistryLite getEmptyRegistry() {
+ if (!doFullRuntimeInheritanceCheck) {
+ return EMPTY_REGISTRY_LITE;
+ }
ExtensionRegistryLite result = emptyRegistry;
if (result == null) {
synchronized (ExtensionRegistryLite.class) {
result = emptyRegistry;
if (result == null) {
- result =
- emptyRegistry =
- doFullRuntimeInheritanceCheck
- ? ExtensionRegistryFactory.createEmpty()
- : EMPTY_REGISTRY_LITE;
+ result = emptyRegistry = ExtensionRegistryFactory.createEmpty();
}
}
}
diff --git a/python/google/protobuf/internal/text_format_test.py b/python/google/protobuf/internal/text_format_test.py
index 49361ee5ee..8377076e99 100644
--- a/python/google/protobuf/internal/text_format_test.py
+++ b/python/google/protobuf/internal/text_format_test.py
@@ -38,6 +38,7 @@ import string
import textwrap
import unittest
+import unittest.mock
from google.protobuf import any_pb2
from google.protobuf import struct_pb2
@@ -2484,5 +2485,3 @@ class OptionalColonMessageToStringTest(unittest.TestCase):
self.assertEqual('repeated_int32: [1]\n', output)
-if __name__ == '__main__':
- unittest.main()
diff --git a/python/google/protobuf/proto_api.h b/python/google/protobuf/proto_api.h
index 9969a91f44..022768e3cd 100644
--- a/python/google/protobuf/proto_api.h
+++ b/python/google/protobuf/proto_api.h
@@ -134,7 +134,7 @@ struct PyProto_API {
inline const char* PyProtoAPICapsuleName() {
static const char kCapsuleName[] =
- "google.protobuf.pyext._message.proto_API";
+ "google3.net.google.protobuf.python.internal.cpp._message.proto_API";
return kCapsuleName;
}
diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc
index abfe0454e9..5baa7b50da 100644
--- a/python/google/protobuf/pyext/message.cc
+++ b/python/google/protobuf/pyext/message.cc
@@ -247,7 +247,7 @@ static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) {
if (WKT_classes == nullptr) {
ScopedPyObjectPtr well_known_types(PyImport_ImportModule(
- "google.protobuf.internal.well_known_types"));
+ "google3.net.google.protobuf.python.internal.well_known_types"));
GOOGLE_DCHECK(well_known_types != nullptr);
WKT_classes = PyObject_GetAttrString(well_known_types.get(), "WKTBASES");
@@ -2372,7 +2372,7 @@ PyObject* DeepCopy(CMessage* self, PyObject* arg) {
PyObject* ToUnicode(CMessage* self) {
// Lazy import to prevent circular dependencies
ScopedPyObjectPtr text_format(
- PyImport_ImportModule("google.protobuf.text_format"));
+ PyImport_ImportModule("google3.net.google.protobuf.python.public.text_format"));
if (text_format == nullptr) {
return nullptr;
}
@@ -3035,7 +3035,7 @@ bool InitProto2MessageModule(PyObject *m) {
reinterpret_cast(&PyMethodDescriptor_Type));
PyObject* enum_type_wrapper = PyImport_ImportModule(
- "google.protobuf.internal.enum_type_wrapper");
+ "google3.net.google.protobuf.python.internal.enum_type_wrapper");
if (enum_type_wrapper == nullptr) {
return false;
}
@@ -3044,7 +3044,7 @@ bool InitProto2MessageModule(PyObject *m) {
Py_DECREF(enum_type_wrapper);
PyObject* message_module = PyImport_ImportModule(
- "google.protobuf.message");
+ "google3.net.google.protobuf.python.public.message");
if (message_module == nullptr) {
return false;
}
diff --git a/python/google/protobuf/pyext/message.h b/python/google/protobuf/pyext/message.h
index b17daa5806..2d2e1f51b2 100644
--- a/python/google/protobuf/pyext/message.h
+++ b/python/google/protobuf/pyext/message.h
@@ -329,7 +329,7 @@ PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg);
return err; \
}
-#define FULL_MODULE_NAME "google.protobuf.pyext._message"
+#define FULL_MODULE_NAME "google3.net.google.protobuf.python.internal.cpp._message"
void FormatTypeError(PyObject* arg, const char* expected_types);
template
diff --git a/python/google/protobuf/text_format.py b/python/google/protobuf/text_format.py
index edb4fba652..a812dc69cb 100644
--- a/python/google/protobuf/text_format.py
+++ b/python/google/protobuf/text_format.py
@@ -67,6 +67,7 @@ _FLOAT_INFINITY = re.compile('-?inf(?:inity)?f?$', re.IGNORECASE)
_FLOAT_NAN = re.compile('nanf?$', re.IGNORECASE)
_QUOTES = frozenset(("'", '"'))
_ANY_FULL_TYPE_NAME = 'google.protobuf.Any'
+_DEBUG_STRING_SILENT_MARKER = '\t '
class Error(Exception):
@@ -880,6 +881,7 @@ class _Parser(object):
type_url_prefix, packed_type_name = self._ConsumeAnyTypeUrl(tokenizer)
tokenizer.Consume(']')
tokenizer.TryConsume(':')
+ self._DetectSilentMarker(tokenizer)
if tokenizer.TryConsume('<'):
expanded_any_end_token = '>'
else:
@@ -979,9 +981,11 @@ class _Parser(object):
if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
tokenizer.TryConsume(':')
+ self._DetectSilentMarker(tokenizer)
merger = self._MergeMessageField
else:
tokenizer.Consume(':')
+ self._DetectSilentMarker(tokenizer)
merger = self._MergeScalarField
if (field.label == descriptor.FieldDescriptor.LABEL_REPEATED and
@@ -999,7 +1003,7 @@ class _Parser(object):
else: # Proto field is unknown.
assert (self.allow_unknown_extension or self.allow_unknown_field)
- _SkipFieldContents(tokenizer)
+ self._SkipFieldContents(tokenizer)
# For historical reasons, fields may optionally be separated by commas or
# semicolons.
@@ -1007,6 +1011,13 @@ class _Parser(object):
tokenizer.TryConsume(';')
+ def _LogSilentMarker(self):
+ pass
+
+ def _DetectSilentMarker(self, tokenizer):
+ if tokenizer.contains_silent_marker_before_current_token:
+ self._LogSilentMarker()
+
def _ConsumeAnyTypeUrl(self, tokenizer):
"""Consumes a google.protobuf.Any type URL and returns the type name."""
# Consume "type.googleapis.com/".
@@ -1161,112 +1172,108 @@ class _Parser(object):
else:
setattr(message, field.name, value)
+ def _SkipFieldContents(self, tokenizer):
+ """Skips over contents (value or message) of a field.
-def _SkipFieldContents(tokenizer):
- """Skips over contents (value or message) of a field.
-
- Args:
- tokenizer: A tokenizer to parse the field name and values.
- """
- # Try to guess the type of this field.
- # If this field is not a message, there should be a ":" between the
- # field name and the field value and also the field value should not
- # start with "{" or "<" which indicates the beginning of a message body.
- # If there is no ":" or there is a "{" or "<" after ":", this field has
- # to be a message or the input is ill-formed.
- if tokenizer.TryConsume(
- ':') and not tokenizer.LookingAt('{') and not tokenizer.LookingAt('<'):
- if tokenizer.LookingAt('['):
- _SkipRepeatedFieldValue(tokenizer)
+ Args:
+ tokenizer: A tokenizer to parse the field name and values.
+ """
+ # Try to guess the type of this field.
+ # If this field is not a message, there should be a ":" between the
+ # field name and the field value and also the field value should not
+ # start with "{" or "<" which indicates the beginning of a message body.
+ # If there is no ":" or there is a "{" or "<" after ":", this field has
+ # to be a message or the input is ill-formed.
+ if tokenizer.TryConsume(
+ ':') and not tokenizer.LookingAt('{') and not tokenizer.LookingAt('<'):
+ self._DetectSilentMarker(tokenizer)
+ if tokenizer.LookingAt('['):
+ self._SkipRepeatedFieldValue(tokenizer)
+ else:
+ self._SkipFieldValue(tokenizer)
else:
- _SkipFieldValue(tokenizer)
- else:
- _SkipFieldMessage(tokenizer)
-
+ self._DetectSilentMarker(tokenizer)
+ self._SkipFieldMessage(tokenizer)
-def _SkipField(tokenizer):
- """Skips over a complete field (name and value/message).
+ def _SkipField(self, tokenizer):
+ """Skips over a complete field (name and value/message).
- Args:
- tokenizer: A tokenizer to parse the field name and values.
- """
- if tokenizer.TryConsume('['):
- # Consume extension or google.protobuf.Any type URL
- tokenizer.ConsumeIdentifier()
- num_identifiers = 1
- while tokenizer.TryConsume('.'):
- tokenizer.ConsumeIdentifier()
- num_identifiers += 1
- # This is possibly a type URL for an Any message.
- if num_identifiers == 3 and tokenizer.TryConsume('/'):
+ Args:
+ tokenizer: A tokenizer to parse the field name and values.
+ """
+ if tokenizer.TryConsume('['):
+ # Consume extension or google.protobuf.Any type URL
tokenizer.ConsumeIdentifier()
+ num_identifiers = 1
while tokenizer.TryConsume('.'):
tokenizer.ConsumeIdentifier()
- tokenizer.Consume(']')
- else:
- tokenizer.ConsumeIdentifierOrNumber()
-
- _SkipFieldContents(tokenizer)
-
- # For historical reasons, fields may optionally be separated by commas or
- # semicolons.
- if not tokenizer.TryConsume(','):
- tokenizer.TryConsume(';')
-
-
-def _SkipFieldMessage(tokenizer):
- """Skips over a field message.
+ num_identifiers += 1
+ # This is possibly a type URL for an Any message.
+ if num_identifiers == 3 and tokenizer.TryConsume('/'):
+ tokenizer.ConsumeIdentifier()
+ while tokenizer.TryConsume('.'):
+ tokenizer.ConsumeIdentifier()
+ tokenizer.Consume(']')
+ else:
+ tokenizer.ConsumeIdentifierOrNumber()
- Args:
- tokenizer: A tokenizer to parse the field name and values.
- """
+ self._SkipFieldContents(tokenizer)
- if tokenizer.TryConsume('<'):
- delimiter = '>'
- else:
- tokenizer.Consume('{')
- delimiter = '}'
+ # For historical reasons, fields may optionally be separated by commas or
+ # semicolons.
+ if not tokenizer.TryConsume(','):
+ tokenizer.TryConsume(';')
- while not tokenizer.LookingAt('>') and not tokenizer.LookingAt('}'):
- _SkipField(tokenizer)
+ def _SkipFieldMessage(self, tokenizer):
+ """Skips over a field message.
- tokenizer.Consume(delimiter)
+ Args:
+ tokenizer: A tokenizer to parse the field name and values.
+ """
+ if tokenizer.TryConsume('<'):
+ delimiter = '>'
+ else:
+ tokenizer.Consume('{')
+ delimiter = '}'
+ while not tokenizer.LookingAt('>') and not tokenizer.LookingAt('}'):
+ self._SkipField(tokenizer)
-def _SkipFieldValue(tokenizer):
- """Skips over a field value.
+ tokenizer.Consume(delimiter)
- Args:
- tokenizer: A tokenizer to parse the field name and values.
+ def _SkipFieldValue(self, tokenizer):
+ """Skips over a field value.
- Raises:
- ParseError: In case an invalid field value is found.
- """
- # String/bytes tokens can come in multiple adjacent string literals.
- # If we can consume one, consume as many as we can.
- if tokenizer.TryConsumeByteString():
- while tokenizer.TryConsumeByteString():
- pass
- return
+ Args:
+ tokenizer: A tokenizer to parse the field name and values.
- if (not tokenizer.TryConsumeIdentifier() and
- not _TryConsumeInt64(tokenizer) and not _TryConsumeUint64(tokenizer) and
- not tokenizer.TryConsumeFloat()):
- raise ParseError('Invalid field value: ' + tokenizer.token)
+ Raises:
+ ParseError: In case an invalid field value is found.
+ """
+ # String/bytes tokens can come in multiple adjacent string literals.
+ # If we can consume one, consume as many as we can.
+ if tokenizer.TryConsumeByteString():
+ while tokenizer.TryConsumeByteString():
+ pass
+ return
+ if (not tokenizer.TryConsumeIdentifier() and
+ not _TryConsumeInt64(tokenizer) and not _TryConsumeUint64(tokenizer) and
+ not tokenizer.TryConsumeFloat()):
+ raise ParseError('Invalid field value: ' + tokenizer.token)
-def _SkipRepeatedFieldValue(tokenizer):
- """Skips over a repeated field value.
+ def _SkipRepeatedFieldValue(self, tokenizer):
+ """Skips over a repeated field value.
- Args:
- tokenizer: A tokenizer to parse the field value.
- """
- tokenizer.Consume('[')
- if not tokenizer.LookingAt(']'):
- _SkipFieldValue(tokenizer)
- while tokenizer.TryConsume(','):
- _SkipFieldValue(tokenizer)
- tokenizer.Consume(']')
+ Args:
+ tokenizer: A tokenizer to parse the field value.
+ """
+ tokenizer.Consume('[')
+ if not tokenizer.LookingAt(']'):
+ self._SkipFieldValue(tokenizer)
+ while tokenizer.TryConsume(','):
+ self._SkipFieldValue(tokenizer)
+ tokenizer.Consume(']')
class Tokenizer(object):
@@ -1307,6 +1314,8 @@ class Tokenizer(object):
self._skip_comments = skip_comments
self._whitespace_pattern = (skip_comments and self._WHITESPACE_OR_COMMENT
or self._WHITESPACE)
+ self.contains_silent_marker_before_current_token = False
+
self._SkipWhitespace()
self.NextToken()
@@ -1339,6 +1348,8 @@ class Tokenizer(object):
match = self._whitespace_pattern.match(self._current_line, self._column)
if not match:
break
+ self.contains_silent_marker_before_current_token = match.group(0) == (
+ ' ' + _DEBUG_STRING_SILENT_MARKER)
length = len(match.group(0))
self._column += length
@@ -1591,6 +1602,7 @@ class Tokenizer(object):
"""Reads the next meaningful token."""
self._previous_line = self._line
self._previous_column = self._column
+ self.contains_silent_marker_before_current_token = False
self._column += len(self.token)
self._SkipWhitespace()
diff --git a/src/Makefile.am b/src/Makefile.am
index fa36d112a5..a396be05c2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -258,6 +258,7 @@ libprotobuf_la_SOURCES = \
google/protobuf/field_mask.pb.cc \
google/protobuf/generated_message_bases.cc \
google/protobuf/generated_message_reflection.cc \
+ google/protobuf/generated_message_tctable_gen.cc \
google/protobuf/generated_message_tctable_full.cc \
google/protobuf/io/gzip_stream.cc \
google/protobuf/io/printer.cc \
diff --git a/src/file_lists.cmake b/src/file_lists.cmake
index 67092cc39e..b1279cb532 100644
--- a/src/file_lists.cmake
+++ b/src/file_lists.cmake
@@ -32,6 +32,7 @@ set(libprotobuf_srcs
${protobuf_SOURCE_DIR}/src/google/protobuf/generated_enum_util.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_bases.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_reflection.cc
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_tctable_gen.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_tctable_full.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_tctable_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_util.cc
diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc
index 0c1bcf9227..30fdac5afc 100644
--- a/src/google/protobuf/arena.cc
+++ b/src/google/protobuf/arena.cc
@@ -117,7 +117,7 @@ SerialArena* SerialArena::New(Memory mem, void* owner,
ThreadSafeArenaStats* stats) {
GOOGLE_DCHECK_LE(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize, mem.size);
ThreadSafeArenaStats::RecordAllocateStats(
- stats, /*requested=*/mem.size, /*allocated=*/mem.size, /*wasted=*/0);
+ stats, /*used=*/0, /*allocated=*/mem.size, /*wasted=*/0);
auto b = new (mem.ptr) Block{nullptr, mem.size};
return new (b->Pointer(kBlockHeaderSize)) SerialArena(b, owner, stats);
}
diff --git a/src/google/protobuf/arenaz_sampler_test.cc b/src/google/protobuf/arenaz_sampler_test.cc
index 67570e87a4..b49c8659ff 100644
--- a/src/google/protobuf/arenaz_sampler_test.cc
+++ b/src/google/protobuf/arenaz_sampler_test.cc
@@ -411,6 +411,33 @@ TEST(ThreadSafeArenazSamplerTest, Callback) {
sampler.Unregister(info2);
}
+TEST(ThreadSafeArenazSamplerTest, InitialBlockReportsZeroUsedAndWasted) {
+ SetThreadSafeArenazEnabled(true);
+ // Setting 1 as the parameter value means one in every two arenas would be
+ // sampled, on average.
+ int32_t oldparam = ThreadSafeArenazSampleParameter();
+ SetThreadSafeArenazSampleParameter(1);
+ SetThreadSafeArenazGlobalNextSample(0);
+ constexpr int kSize = 571;
+ int count_found_allocation = 0;
+ auto& sampler = GlobalThreadSafeArenazSampler();
+ for (int i = 0; i < 10; ++i) {
+ char block[kSize];
+ google::protobuf::Arena arena(/*initial_block=*/block, /*initial_block_size=*/kSize);
+ sampler.Iterate([&](const ThreadSafeArenaStats& h) {
+ const auto& histbin =
+ h.block_histogram[ThreadSafeArenaStats::FindBin(kSize)];
+ if (histbin.bytes_allocated.load(std::memory_order_relaxed) == kSize) {
+ count_found_allocation++;
+ EXPECT_EQ(histbin.bytes_used, 0);
+ EXPECT_EQ(histbin.bytes_wasted, 0);
+ }
+ });
+ }
+ EXPECT_GT(count_found_allocation, 0);
+ SetThreadSafeArenazSampleParameter(oldparam);
+}
+
class ThreadSafeArenazSamplerTestThread : public Thread {
protected:
void Run() override {
diff --git a/src/google/protobuf/compiler/cpp/enum_field.cc b/src/google/protobuf/compiler/cpp/enum_field.cc
index 3539a0df41..1e4389bfe9 100644
--- a/src/google/protobuf/compiler/cpp/enum_field.cc
+++ b/src/google/protobuf/compiler/cpp/enum_field.cc
@@ -104,7 +104,7 @@ void EnumFieldGenerator::GenerateInlineAccessorDefinitions(
" return _internal_$name$();\n"
"}\n"
"inline void $classname$::_internal_set_$name$($type$ value) {\n");
- if (!HasPreservingUnknownEnumSemantics(descriptor_)) {
+ if (!internal::cpp::HasPreservingUnknownEnumSemantics(descriptor_)) {
format(" assert($type$_IsValid(value));\n");
}
format(
@@ -204,7 +204,7 @@ void EnumOneofFieldGenerator::GenerateInlineAccessorDefinitions(
" return _internal_$name$();\n"
"}\n"
"inline void $classname$::_internal_set_$name$($type$ value) {\n");
- if (!HasPreservingUnknownEnumSemantics(descriptor_)) {
+ if (!internal::cpp::HasPreservingUnknownEnumSemantics(descriptor_)) {
format(" assert($type$_IsValid(value));\n");
}
format(
@@ -291,7 +291,7 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions(
" return _internal_$name$(index);\n"
"}\n"
"inline void $classname$::set_$name$(int index, $type$ value) {\n");
- if (!HasPreservingUnknownEnumSemantics(descriptor_)) {
+ if (!internal::cpp::HasPreservingUnknownEnumSemantics(descriptor_)) {
format(" assert($type$_IsValid(value));\n");
}
format(
@@ -300,7 +300,7 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions(
" // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n"
"inline void $classname$::_internal_add_$name$($type$ value) {\n");
- if (!HasPreservingUnknownEnumSemantics(descriptor_)) {
+ if (!internal::cpp::HasPreservingUnknownEnumSemantics(descriptor_)) {
format(" assert($type$_IsValid(value));\n");
}
format(
diff --git a/src/google/protobuf/compiler/cpp/field.cc b/src/google/protobuf/compiler/cpp/field.cc
index 90d20848b3..fdd31abff1 100644
--- a/src/google/protobuf/compiler/cpp/field.cc
+++ b/src/google/protobuf/compiler/cpp/field.cc
@@ -267,7 +267,7 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
}
void FieldGenerator::SetHasBitIndex(int32_t has_bit_index) {
- if (!HasHasbit(descriptor_)) {
+ if (!internal::cpp::HasHasbit(descriptor_)) {
GOOGLE_CHECK_EQ(has_bit_index, -1);
return;
}
diff --git a/src/google/protobuf/compiler/cpp/file.cc b/src/google/protobuf/compiler/cpp/file.cc
index 502d8c007e..0a73e3e418 100644
--- a/src/google/protobuf/compiler/cpp/file.cc
+++ b/src/google/protobuf/compiler/cpp/file.cc
@@ -51,6 +51,7 @@
#include
#include
#include
+#include
#include
// Must be last.
diff --git a/src/google/protobuf/compiler/cpp/helpers.cc b/src/google/protobuf/compiler/cpp/helpers.cc
index d182c8607f..b3ceafb5fa 100644
--- a/src/google/protobuf/compiler/cpp/helpers.cc
+++ b/src/google/protobuf/compiler/cpp/helpers.cc
@@ -1133,39 +1133,16 @@ bool IsWellKnownMessage(const FileDescriptor* file) {
return well_known_files.find(file->name()) != well_known_files.end();
}
-static bool FieldEnforceUtf8(const FieldDescriptor* field,
- const Options& options) {
- return true;
-}
-
-static bool FileUtf8Verification(const FileDescriptor* file,
- const Options& options) {
- return true;
-}
-
-// Which level of UTF-8 enforcemant is placed on this file.
-Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field,
- const Options& options) {
- if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
- FieldEnforceUtf8(field, options)) {
- return Utf8CheckMode::kStrict;
- } else if (GetOptimizeFor(field->file(), options) !=
- FileOptions::LITE_RUNTIME &&
- FileUtf8Verification(field->file(), options)) {
- return Utf8CheckMode::kVerify;
- } else {
- return Utf8CheckMode::kNone;
- }
-}
-
static void GenerateUtf8CheckCode(const FieldDescriptor* field,
const Options& options, bool for_parse,
const char* parameters,
const char* strict_function,
const char* verify_function,
const Formatter& format) {
- switch (GetUtf8CheckMode(field, options)) {
- case Utf8CheckMode::kStrict: {
+ switch (internal::cpp::GetUtf8CheckMode(
+ field,
+ GetOptimizeFor(field->file(), options) == FileOptions::LITE_RUNTIME)) {
+ case internal::cpp::Utf8CheckMode::kStrict: {
if (for_parse) {
format("DO_(");
}
@@ -1185,7 +1162,7 @@ static void GenerateUtf8CheckCode(const FieldDescriptor* field,
format.Outdent();
break;
}
- case Utf8CheckMode::kVerify: {
+ case internal::cpp::Utf8CheckMode::kVerify: {
format("::$proto_ns$::internal::WireFormat::$1$(\n", verify_function);
format.Indent();
format(parameters);
@@ -1198,7 +1175,7 @@ static void GenerateUtf8CheckCode(const FieldDescriptor* field,
format.Outdent();
break;
}
- case Utf8CheckMode::kNone:
+ case internal::cpp::Utf8CheckMode::kNone:
break;
}
}
diff --git a/src/google/protobuf/compiler/cpp/helpers.h b/src/google/protobuf/compiler/cpp/helpers.h
index 21a488e2a5..12bc9bbd1c 100644
--- a/src/google/protobuf/compiler/cpp/helpers.h
+++ b/src/google/protobuf/compiler/cpp/helpers.h
@@ -462,28 +462,6 @@ inline bool IsProto3(const FileDescriptor* file) {
return file->syntax() == FileDescriptor::SYNTAX_PROTO3;
}
-inline bool HasHasbit(const FieldDescriptor* field) {
- // This predicate includes proto3 message fields only if they have "optional".
- // Foo submsg1 = 1; // HasHasbit() == false
- // optional Foo submsg2 = 2; // HasHasbit() == true
- // This is slightly odd, as adding "optional" to a singular proto3 field does
- // not change the semantics or API. However whenever any field in a message
- // has a hasbit, it forces reflection to include hasbit offsets for *all*
- // fields, even if almost all of them are set to -1 (no hasbit). So to avoid
- // causing a sudden size regression for ~all proto3 messages, we give proto3
- // message fields a hasbit only if "optional" is present. If the user is
- // explicitly writing "optional", it is likely they are writing it on
- // primitive fields also.
- return (field->has_optional_keyword() || field->is_required()) &&
- !field->options().weak();
-}
-
-// Returns true if 'enum' semantics are such that unknown values are preserved
-// in the enum field itself, rather than going to the UnknownFieldSet.
-inline bool HasPreservingUnknownEnumSemantics(const FieldDescriptor* field) {
- return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3;
-}
-
inline bool IsCrossFileMessage(const FieldDescriptor* field) {
return field->type() == FieldDescriptor::TYPE_MESSAGE &&
field->message_type()->file() != field->file();
@@ -935,15 +913,6 @@ class PROTOC_EXPORT NamespaceOpener {
std::vector name_stack_;
};
-enum class Utf8CheckMode {
- kStrict = 0, // Parsing will fail if non UTF-8 data is in string fields.
- kVerify = 1, // Only log an error but parsing will succeed.
- kNone = 2, // No UTF-8 check.
-};
-
-Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field,
- const Options& options);
-
void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
const Options& options, bool for_parse,
const char* parameters,
@@ -954,43 +923,6 @@ void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field,
const char* parameters,
const Formatter& format);
-template
-struct FieldRangeImpl {
- struct Iterator {
- using iterator_category = std::forward_iterator_tag;
- using value_type = const FieldDescriptor*;
- using difference_type = int;
-
- value_type operator*() { return descriptor->field(idx); }
-
- friend bool operator==(const Iterator& a, const Iterator& b) {
- GOOGLE_DCHECK(a.descriptor == b.descriptor);
- return a.idx == b.idx;
- }
- friend bool operator!=(const Iterator& a, const Iterator& b) {
- return !(a == b);
- }
-
- Iterator& operator++() {
- idx++;
- return *this;
- }
-
- int idx;
- const T* descriptor;
- };
-
- Iterator begin() const { return {0, descriptor}; }
- Iterator end() const { return {descriptor->field_count(), descriptor}; }
-
- const T* descriptor;
-};
-
-template
-FieldRangeImpl FieldRange(const T* desc) {
- return {desc};
-}
-
struct OneOfRangeImpl {
struct Iterator {
using iterator_category = std::forward_iterator_tag;
diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc
index 50b86f7b2b..d37e70c329 100644
--- a/src/google/protobuf/compiler/cpp/message.cc
+++ b/src/google/protobuf/compiler/cpp/message.cc
@@ -37,8 +37,10 @@
#include
#include
#include
+#include
#include