PROTOBUF_SYNC_PIPER
pull/10254/head
Joshua Haberman 3 years ago
commit 887daf693f
  1. 2
      .github/ISSUE_TEMPLATE/bug_report.md
  2. 2
      .github/ISSUE_TEMPLATE/feature_request.md
  3. 24
      .github/workflows/generated_cmake.yml
  4. 22
      BUILD.bazel
  5. 4
      Makefile.am
  6. 5
      benchmarks/java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java
  7. 2
      conformance/conformance_cpp.cc
  8. 7
      csharp/BUILD.bazel
  9. 17
      csharp/build_release.sh
  10. BIN
      csharp/src/Google.Protobuf.Test/testprotos.pb
  11. 100
      csharp/src/Google.Protobuf/Reflection/Descriptor.cs
  12. 5
      java/core/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java
  13. 1
      kokoro/linux/bazel_distcheck/build.sh
  14. 1
      pkg/BUILD.bazel
  15. 16
      python/google/protobuf/internal/descriptor_test.py
  16. 20
      python/google/protobuf/internal/message_test.py
  17. 2
      src/google/protobuf/arena.cc
  18. 34
      src/google/protobuf/arena.h
  19. 54
      src/google/protobuf/arena_unittest.cc
  20. 3
      src/google/protobuf/compiler/command_line_interface.cc
  21. 7
      src/google/protobuf/compiler/cpp/helpers.cc
  22. 5
      src/google/protobuf/compiler/cpp/helpers.h
  23. 20
      src/google/protobuf/compiler/cpp/message.cc
  24. 26
      src/google/protobuf/compiler/subprocess.cc
  25. 7
      src/google/protobuf/generated_message_tctable_impl.h
  26. 4
      src/google/protobuf/io/coded_stream.h
  27. 54
      src/google/protobuf/map.h
  28. 55
      src/google/protobuf/map_test.inc
  29. 14
      src/google/protobuf/port_def.inc
  30. 1
      src/google/protobuf/port_undef.inc
  31. 6
      src/google/protobuf/repeated_field.h
  32. 2
      src/google/protobuf/util/BUILD.bazel
  33. 12
      src/google/protobuf/util/json_util.h
  34. 7
      src/google/protobuf/util/json_util_test.cc
  35. 8
      update_file_lists.sh

@ -2,7 +2,7 @@
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
labels: 'untriaged'
assignees: ''
---

@ -2,7 +2,7 @@
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
labels: 'untriaged'
assignees: ''
---

@ -0,0 +1,24 @@
name: Generated CMake File Lists
on:
- push
- pull_request
jobs:
cmake:
runs-on: ubuntu-latest
strategy:
fail-fast: false # Don't cancel all jobs if one fails.
steps:
- uses: actions/checkout@v2
- name: Set up Bazel read-only caching
run: echo "BAZEL_CACHE_AUTH=--remote_upload_local_results=false" >> $GITHUB_ENV
- name: Generate CMake files
run: cd ${{ github.workspace }} && bazel build //pkg:gen_src_file_lists --test_output=errors $BAZEL_CACHE $BAZEL_CACHE_AUTH
- name: Compare to Golden file
run: diff -du bazel-bin/pkg/src_file_lists.cmake src/file_lists.cmake
- name: Report
run: echo "::error file=cmake/update_file_lists.sh::CMake files are stale, please run cmake/update_file_lists.sh"
if: failure()

@ -386,25 +386,6 @@ alias(
visibility = ["//visibility:public"],
)
# TODO: re-enable this test if appropriate, or replace with something that
# uses the new setup.
# sh_test(
# name = "build_files_updated_unittest",
# srcs = [
# "build_files_updated_unittest.sh",
# ],
# data = [
# "BUILD",
# "cmake/extract_includes.bat.in",
# "cmake/libprotobuf.cmake",
# "cmake/libprotobuf-lite.cmake",
# "cmake/libprotoc.cmake",
# "cmake/tests.cmake",
# "src/Makefile.am",
# "update_file_lists.sh",
# ],
# )
java_proto_library(
name = "test_messages_proto2_java_proto",
visibility = [
@ -488,12 +469,11 @@ pkg_files(
"README.md",
"WORKSPACE",
"autogen.sh",
"build_files_updated_unittest.sh",
"cmake/CMakeLists.txt",
"cmake/README.md",
"cmake/update_file_lists.sh",
"generate_descriptor_proto.sh",
"maven_install.json",
"update_file_lists.sh",
"//third_party:BUILD.bazel",
"//third_party:zlib.BUILD",
"//util/python:BUILD.bazel",

@ -62,6 +62,7 @@ csharp_EXTRA_DIST= \
csharp/NuGet.Config \
csharp/README.md \
csharp/build_packages.bat \
csharp/build_release.sh \
csharp/build_tools.sh \
csharp/buildall.bat \
csharp/buildall.sh \
@ -1201,7 +1202,6 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \
LICENSE \
CONTRIBUTORS.txt \
CHANGES.txt \
update_file_lists.sh \
BUILD.bazel \
WORKSPACE \
CMakeLists.txt \
@ -1209,7 +1209,6 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \
build_defs/cc_proto_blacklist_test.bzl \
build_defs/compiler_config_setting.bzl \
build_defs/cpp_opts.bzl \
build_files_updated_unittest.sh \
cmake/CMakeLists.txt \
cmake/README.md \
cmake/conformance.cmake \
@ -1226,6 +1225,7 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \
cmake/protobuf-options.cmake \
cmake/protobuf.pc.cmake \
cmake/protoc.cmake \
cmake/update_file_lists.sh \
cmake/tests.cmake \
cmake/version.rc.in \
csharp/BUILD.bazel \

@ -12,9 +12,8 @@ import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;
/**
* Basic benchmarks for Java protobuf parsing.
*/
/** Basic benchmarks for Java protobuf parsing. */
@SuppressWarnings("CheckReturnValue")
public class ProtoCaliperBenchmark {
public enum BenchmarkMessageType {
GOOGLE_MESSAGE1_PROTO3 {

@ -232,7 +232,7 @@ util::StatusOr<bool> Harness::ServeConformanceRequest() {
std::string serialized_input;
serialized_input.resize(in_len);
RETURN_IF_ERROR(ReadFd(STDIN_FILENO, serialized_input.data(), in_len));
RETURN_IF_ERROR(ReadFd(STDIN_FILENO, &serialized_input[0], in_len));
ConformanceRequest request;
GOOGLE_CHECK(request.ParseFromString(serialized_input));

@ -39,6 +39,7 @@ pkg_files(
"NuGet.Config",
"README.md",
"build_packages.bat",
"build_release.sh",
"build_tools.sh",
"buildall.bat",
"buildall.sh",
@ -51,3 +52,9 @@ pkg_files(
strip_prefix = strip_prefix.from_root(""),
visibility = ["//pkg:__pkg__"],
)
sh_binary(
name = "release",
srcs = ["build_release.sh"],
args = ["$(location build_release.sh)"],
)

@ -0,0 +1,17 @@
#!/bin/bash
cd $(dirname $(readlink $BASH_SOURCE))
# Disable some unwanted dotnet options
set DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true
set DOTNET_CLI_TELEMETRY_OPTOUT=true
# Work around https://github.com/dotnet/core/issues/5881
dotnet nuget locals all --clear
# Builds Google.Protobuf NuGet packages
dotnet restore src/Google.Protobuf.sln
dotnet pack -c Release src/Google.Protobuf.sln -p:ContinuousIntegrationBuild=true
# This requires built protoc executables as specified in the nusepc
nuget pack Google.Protobuf.Tools.nuspec

@ -152,14 +152,17 @@ namespace Google.Protobuf.Reflection {
"bGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ahgEKCExvY2F0",
"aW9uEhAKBHBhdGgYASADKAVCAhABEhAKBHNwYW4YAiADKAVCAhABEhgKEGxl",
"YWRpbmdfY29tbWVudHMYAyABKAkSGQoRdHJhaWxpbmdfY29tbWVudHMYBCAB",
"KAkSIQoZbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cxgGIAMoCSKnAQoRR2Vu",
"KAkSIQoZbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cxgGIAMoCSKcAgoRR2Vu",
"ZXJhdGVkQ29kZUluZm8SQQoKYW5ub3RhdGlvbhgBIAMoCzItLmdvb2dsZS5w",
"cm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uGk8KCkFubm90",
"YXRpb24SEAoEcGF0aBgBIAMoBUICEAESEwoLc291cmNlX2ZpbGUYAiABKAkS",
"DQoFYmVnaW4YAyABKAUSCwoDZW5kGAQgASgFQn4KE2NvbS5nb29nbGUucHJv",
"dG9idWZCEERlc2NyaXB0b3JQcm90b3NIAVotZ29vZ2xlLmdvbGFuZy5vcmcv",
"cHJvdG9idWYvdHlwZXMvZGVzY3JpcHRvcnBi+AEBogIDR1BCqgIaR29vZ2xl",
"LlByb3RvYnVmLlJlZmxlY3Rpb24="));
"cm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uGsMBCgpBbm5v",
"dGF0aW9uEhAKBHBhdGgYASADKAVCAhABEhMKC3NvdXJjZV9maWxlGAIgASgJ",
"Eg0KBWJlZ2luGAMgASgFEgsKA2VuZBgEIAEoBRJICghzZW1hbnRpYxgFIAEo",
"DjI2Lmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0",
"aW9uLlNlbWFudGljIigKCFNlbWFudGljEggKBE5PTkUQABIHCgNTRVQQARIJ",
"CgVBTElBUxACQn4KE2NvbS5nb29nbGUucHJvdG9idWZCEERlc2NyaXB0b3JQ",
"cm90b3NIAVotZ29vZ2xlLmdvbGFuZy5vcmcvcHJvdG9idWYvdHlwZXMvZGVz",
"Y3JpcHRvcnBi+AEBogIDR1BCqgIaR29vZ2xlLlByb3RvYnVmLlJlZmxlY3Rp",
"b24="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
@ -184,7 +187,7 @@ namespace Google.Protobuf.Reflection {
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MethodOptions), global::Google.Protobuf.Reflection.MethodOptions.Parser, new[]{ "Deprecated", "IdempotencyLevel", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.MethodOptions.Types.IdempotencyLevel) }, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.UninterpretedOption), global::Google.Protobuf.Reflection.UninterpretedOption.Parser, new[]{ "Name", "IdentifierValue", "PositiveIntValue", "NegativeIntValue", "DoubleValue", "StringValue", "AggregateValue" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart), global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart.Parser, new[]{ "NamePart_", "IsExtension" }, null, null, null, null)}),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.SourceCodeInfo), global::Google.Protobuf.Reflection.SourceCodeInfo.Parser, new[]{ "Location" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location), global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location.Parser, new[]{ "Path", "Span", "LeadingComments", "TrailingComments", "LeadingDetachedComments" }, null, null, null, null)}),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.GeneratedCodeInfo), global::Google.Protobuf.Reflection.GeneratedCodeInfo.Parser, new[]{ "Annotation" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation), global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Parser, new[]{ "Path", "SourceFile", "Begin", "End" }, null, null, null, null)})
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.GeneratedCodeInfo), global::Google.Protobuf.Reflection.GeneratedCodeInfo.Parser, new[]{ "Annotation" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation), global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Parser, new[]{ "Path", "SourceFile", "Begin", "End", "Semantic" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Types.Semantic) }, null, null)})
}));
}
#endregion
@ -10811,6 +10814,7 @@ namespace Google.Protobuf.Reflection {
sourceFile_ = other.sourceFile_;
begin_ = other.begin_;
end_ = other.end_;
semantic_ = other.semantic_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
@ -10902,7 +10906,7 @@ namespace Google.Protobuf.Reflection {
private int end_;
/// <summary>
/// Identifies the ending offset in bytes in the generated code that
/// relates to the identified offset. The end offset should be one past
/// relates to the identified object. The end offset should be one past
/// the last relevant byte (so the length of the text = end - begin).
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -10927,6 +10931,33 @@ namespace Google.Protobuf.Reflection {
_hasBits0 &= ~2;
}
/// <summary>Field number for the "semantic" field.</summary>
public const int SemanticFieldNumber = 5;
private readonly static global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Types.Semantic SemanticDefaultValue = global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Types.Semantic.None;
private global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Types.Semantic semantic_;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Types.Semantic Semantic {
get { if ((_hasBits0 & 4) != 0) { return semantic_; } else { return SemanticDefaultValue; } }
set {
_hasBits0 |= 4;
semantic_ = value;
}
}
/// <summary>Gets whether the "semantic" field is set</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public bool HasSemantic {
get { return (_hasBits0 & 4) != 0; }
}
/// <summary>Clears the value of the "semantic" field</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void ClearSemantic() {
_hasBits0 &= ~4;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public override bool Equals(object other) {
@ -10946,6 +10977,7 @@ namespace Google.Protobuf.Reflection {
if (SourceFile != other.SourceFile) return false;
if (Begin != other.Begin) return false;
if (End != other.End) return false;
if (Semantic != other.Semantic) return false;
return Equals(_unknownFields, other._unknownFields);
}
@ -10957,6 +10989,7 @@ namespace Google.Protobuf.Reflection {
if (HasSourceFile) hash ^= SourceFile.GetHashCode();
if (HasBegin) hash ^= Begin.GetHashCode();
if (HasEnd) hash ^= End.GetHashCode();
if (HasSemantic) hash ^= Semantic.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
@ -10988,6 +11021,10 @@ namespace Google.Protobuf.Reflection {
output.WriteRawTag(32);
output.WriteInt32(End);
}
if (HasSemantic) {
output.WriteRawTag(40);
output.WriteEnum((int) Semantic);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
@ -11011,6 +11048,10 @@ namespace Google.Protobuf.Reflection {
output.WriteRawTag(32);
output.WriteInt32(End);
}
if (HasSemantic) {
output.WriteRawTag(40);
output.WriteEnum((int) Semantic);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
@ -11031,6 +11072,9 @@ namespace Google.Protobuf.Reflection {
if (HasEnd) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(End);
}
if (HasSemantic) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Semantic);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
@ -11053,6 +11097,9 @@ namespace Google.Protobuf.Reflection {
if (other.HasEnd) {
End = other.End;
}
if (other.HasSemantic) {
Semantic = other.Semantic;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
@ -11085,6 +11132,10 @@ namespace Google.Protobuf.Reflection {
End = input.ReadInt32();
break;
}
case 40: {
Semantic = (global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Types.Semantic) input.ReadEnum();
break;
}
}
}
#endif
@ -11117,11 +11168,42 @@ namespace Google.Protobuf.Reflection {
End = input.ReadInt32();
break;
}
case 40: {
Semantic = (global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Types.Semantic) input.ReadEnum();
break;
}
}
}
}
#endif
#region Nested types
/// <summary>Container for nested types declared in the Annotation message type.</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public static partial class Types {
/// <summary>
/// Represents the identified object's effect on the element in the original
/// .proto file.
/// </summary>
public enum Semantic {
/// <summary>
/// There is no effect or the effect is indescribable.
/// </summary>
[pbr::OriginalName("NONE")] None = 0,
/// <summary>
/// The element is set or otherwise mutated.
/// </summary>
[pbr::OriginalName("SET")] Set = 1,
/// <summary>
/// An alias to the element is returned.
/// </summary>
[pbr::OriginalName("ALIAS")] Alias = 2,
}
}
#endregion
}
}

@ -30,14 +30,13 @@
package com.google.protobuf;
import junit.framework.TestCase;
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Bar;
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.BarPrime;
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Foo;
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestOneofEquals;
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestRecursiveOneof;
import junit.framework.TestCase;
/**
* Test generate equal and hash methods for the lite runtime.
*
@ -120,6 +119,6 @@ public class LiteEqualsAndHashTest extends TestCase {
public void testRecursiveHashcode() {
// This tests that we don't infinite loop.
TestRecursiveOneof.getDefaultInstance().hashCode();
int unused = TestRecursiveOneof.getDefaultInstance().hashCode();
}
}

@ -55,6 +55,7 @@ bazel_args=(
--
//...
-//objectivec/... # only works on macOS
-//csharp/... # release builds require external dependencies
@com_google_protobuf_examples//...
)
${SCRIPT_ROOT}/kokoro/common/bazel_wrapper.sh "${bazel_args[@]}"

@ -400,6 +400,7 @@ cc_dist_library(
"//src/google/protobuf/util:differencer",
"//src/google/protobuf/util:field_mask_util",
"//src/google/protobuf/util:json_util",
"//src/google/protobuf/util:zero_copy_sink",
"//src/google/protobuf/util:time_util",
"//src/google/protobuf/util:type_resolver_util",
"//src/google/protobuf/util/internal:datapiece",

@ -118,6 +118,22 @@ class DescriptorTest(unittest.TestCase):
def GetDescriptorPool(self):
return symbol_database.Default().pool
def testMissingPackage(self):
file_proto = descriptor_pb2.FileDescriptorProto(
name='some/filename/some.proto')
serialized = file_proto.SerializeToString()
pool = descriptor_pool.DescriptorPool()
file_descriptor = pool.AddSerializedFile(serialized)
self.assertEqual('', file_descriptor.package)
def testEmptyPackage(self):
file_proto = descriptor_pb2.FileDescriptorProto(
name='some/filename/some.proto', package='')
serialized = file_proto.SerializeToString()
pool = descriptor_pool.DescriptorPool()
file_descriptor = pool.AddSerializedFile(serialized)
self.assertEqual('', file_descriptor.package)
def testFindMethodByName(self):
service_descriptor = (unittest_custom_options_pb2.
TestServiceWithCustomOptions.DESCRIPTOR)

@ -2455,6 +2455,26 @@ class Proto3Test(unittest.TestCase):
with self.assertRaises(ValueError):
unittest_proto3_arena_pb2.TestAllTypes(optional_string=u'\ud801\ud801')
def testCrashNullAA(self):
self.assertEqual(
unittest_proto3_arena_pb2.TestAllTypes.NestedMessage(),
unittest_proto3_arena_pb2.TestAllTypes.NestedMessage())
def testCrashNullAB(self):
self.assertEqual(
unittest_proto3_arena_pb2.TestAllTypes.NestedMessage(),
unittest_proto3_arena_pb2.TestAllTypes().optional_nested_message)
def testCrashNullBA(self):
self.assertEqual(
unittest_proto3_arena_pb2.TestAllTypes().optional_nested_message,
unittest_proto3_arena_pb2.TestAllTypes.NestedMessage())
def testCrashNullBB(self):
self.assertEqual(
unittest_proto3_arena_pb2.TestAllTypes().optional_nested_message,
unittest_proto3_arena_pb2.TestAllTypes().optional_nested_message)

@ -382,7 +382,7 @@ void ThreadSafeArena::Init() {
void ThreadSafeArena::SetInitialBlock(void* mem, size_t size) {
SerialArena* serial = SerialArena::New({mem, size}, &thread_cache(),
arena_stats_.MutableStats());
serial->set_next(NULL);
serial->set_next(nullptr);
threads_.store(serial, std::memory_order_relaxed);
CacheSerialArena(serial);
}

@ -120,7 +120,7 @@ struct ArenaOptions {
// here.
size_t max_block_size;
// An initial block of memory for the arena to use, or NULL for none. If
// An initial block of memory for the arena to use, or nullptr for none. If
// provided, the block must live at least as long as the arena itself. The
// creator of the Arena retains ownership of the block after the Arena is
// destroyed.
@ -143,7 +143,7 @@ struct ArenaOptions {
ArenaOptions()
: start_block_size(internal::AllocationPolicy::kDefaultStartBlockSize),
max_block_size(internal::AllocationPolicy::kDefaultMaxBlockSize),
initial_block(NULL),
initial_block(nullptr),
initial_block_size(0),
block_alloc(nullptr),
block_dealloc(nullptr),
@ -180,7 +180,7 @@ struct ArenaOptions {
#if PROTOBUF_RTTI
#define RTTI_TYPE_ID(type) (&typeid(type))
#else
#define RTTI_TYPE_ID(type) (NULL)
#define RTTI_TYPE_ID(type) (nullptr)
#endif
// Arena allocator. Arena allocation replaces ordinary (heap-based) allocation
@ -210,7 +210,7 @@ struct ArenaOptions {
// with `args` (without `arena`), called when a T is allocated on the heap;
// and a constructor callable with `Arena* arena, Args&&... args`, called when
// a T is allocated on an arena. If the second constructor is called with a
// NULL arena pointer, it must be equivalent to invoking the first
// null arena pointer, it must be equivalent to invoking the first
// (`args`-only) constructor.
//
// - The type T must have a particular type trait: a nested type
@ -220,7 +220,7 @@ struct ArenaOptions {
//
// - The type T *may* have the type trait |DestructorSkippable_|. If this type
// trait is present in the type, then its destructor will not be called if and
// only if it was passed a non-NULL arena pointer. If this type trait is not
// only if it was passed a non-null arena pointer. If this type trait is not
// present on the type, then its destructor is always called when the
// containing arena is destroyed.
//
@ -263,9 +263,9 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final {
void Init(const ArenaOptions&) {}
// API to create proto2 message objects on the arena. If the arena passed in
// is NULL, then a heap allocated object is returned. Type T must be a message
// defined in a .proto file with cc_enable_arenas set to true, otherwise a
// compilation error will occur.
// is nullptr, then a heap allocated object is returned. Type T must be a
// message defined in a .proto file with cc_enable_arenas set to true,
// otherwise a compilation error will occur.
//
// RepeatedField and RepeatedPtrField may also be instantiated directly on an
// arena with this method.
@ -342,7 +342,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final {
"CreateArray requires a trivially destructible type");
GOOGLE_CHECK_LE(num_elements, std::numeric_limits<size_t>::max() / sizeof(T))
<< "Requested size is too large to fit into size_t.";
if (arena == NULL) {
if (arena == nullptr) {
return static_cast<T*>(::operator new[](num_elements * sizeof(T)));
} else {
return arena->CreateInternalRawArray<T>(num_elements);
@ -386,7 +386,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final {
// arena-allocated memory.
template <typename T>
PROTOBUF_ALWAYS_INLINE void OwnDestructor(T* object) {
if (object != NULL) {
if (object != nullptr) {
impl_.AddCleanup(object, &internal::cleanup::arena_destruct_object<T>);
}
}
@ -401,9 +401,9 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final {
}
// Retrieves the arena associated with |value| if |value| is an arena-capable
// 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.
// message, or nullptr 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);
@ -568,7 +568,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final {
static_assert(
InternalHelper<T>::is_arena_constructable::value,
"CreateMessage can only construct types that are ArenaConstructable");
if (arena == NULL) {
if (arena == nullptr) {
return new T(nullptr, static_cast<Args&&>(args)...);
} else {
return arena->DoCreateMessage<T>(static_cast<Args&&>(args)...);
@ -583,7 +583,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final {
static_assert(
InternalHelper<T>::is_arena_constructable::value,
"CreateMessage can only construct types that are ArenaConstructable");
if (arena == NULL) {
if (arena == nullptr) {
// Generated arena constructor T(Arena*) is protected. Call via
// InternalHelper.
return InternalHelper<T>::New();
@ -730,13 +730,13 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final {
// using the virtual destructor instead.
template <typename T>
PROTOBUF_ALWAYS_INLINE void OwnInternal(T* object, std::true_type) {
if (object != NULL) {
if (object != nullptr) {
impl_.AddCleanup(object, &internal::arena_delete_object<MessageLite>);
}
}
template <typename T>
PROTOBUF_ALWAYS_INLINE void OwnInternal(T* object, std::false_type) {
if (object != NULL) {
if (object != nullptr) {
impl_.AddCleanup(object, &internal::arena_delete_object<T>);
}
}

@ -84,10 +84,10 @@ class Notifier {
class SimpleDataType {
public:
SimpleDataType() : notifier_(NULL) {}
SimpleDataType() : notifier_(nullptr) {}
void SetNotifier(Notifier* notifier) { notifier_ = notifier; }
virtual ~SimpleDataType() {
if (notifier_ != NULL) {
if (notifier_ != nullptr) {
notifier_->Notify();
}
};
@ -171,17 +171,17 @@ TEST(ArenaTest, DestructorSkippable) {
TEST(ArenaTest, BasicCreate) {
Arena arena;
EXPECT_TRUE(Arena::Create<int32_t>(&arena) != NULL);
EXPECT_TRUE(Arena::Create<int64_t>(&arena) != NULL);
EXPECT_TRUE(Arena::Create<float>(&arena) != NULL);
EXPECT_TRUE(Arena::Create<double>(&arena) != NULL);
EXPECT_TRUE(Arena::Create<std::string>(&arena) != NULL);
EXPECT_TRUE(Arena::Create<int32_t>(&arena) != nullptr);
EXPECT_TRUE(Arena::Create<int64_t>(&arena) != nullptr);
EXPECT_TRUE(Arena::Create<float>(&arena) != nullptr);
EXPECT_TRUE(Arena::Create<double>(&arena) != nullptr);
EXPECT_TRUE(Arena::Create<std::string>(&arena) != nullptr);
arena.Own(new int32_t);
arena.Own(new int64_t);
arena.Own(new float);
arena.Own(new double);
arena.Own(new std::string);
arena.Own<int>(NULL);
arena.Own<int>(nullptr);
Notifier notifier;
SimpleDataType* data = Arena::Create<SimpleDataType>(&arena);
data->SetNotifier(&notifier);
@ -196,7 +196,7 @@ TEST(ArenaTest, CreateAndConstCopy) {
Arena arena;
const std::string s("foo");
const std::string* s_copy = Arena::Create<std::string>(&arena, s);
EXPECT_TRUE(s_copy != NULL);
EXPECT_TRUE(s_copy != nullptr);
EXPECT_EQ("foo", s);
EXPECT_EQ("foo", *s_copy);
}
@ -205,7 +205,7 @@ TEST(ArenaTest, CreateAndNonConstCopy) {
Arena arena;
std::string s("foo");
const std::string* s_copy = Arena::Create<std::string>(&arena, s);
EXPECT_TRUE(s_copy != NULL);
EXPECT_TRUE(s_copy != nullptr);
EXPECT_EQ("foo", s);
EXPECT_EQ("foo", *s_copy);
}
@ -214,7 +214,7 @@ TEST(ArenaTest, CreateAndMove) {
Arena arena;
std::string s("foo");
const std::string* s_move = Arena::Create<std::string>(&arena, std::move(s));
EXPECT_TRUE(s_move != NULL);
EXPECT_TRUE(s_move != nullptr);
EXPECT_TRUE(s.empty()); // NOLINT
EXPECT_EQ("foo", *s_move);
}
@ -226,7 +226,7 @@ TEST(ArenaTest, CreateWithFourConstructorArguments) {
const MustBeConstructedWithOneThroughFour* new_object =
Arena::Create<MustBeConstructedWithOneThroughFour>(&arena, 1, "2", three,
&four);
EXPECT_TRUE(new_object != NULL);
EXPECT_TRUE(new_object != nullptr);
ASSERT_EQ(1, new_object->one_);
ASSERT_STREQ("2", new_object->two_);
ASSERT_EQ("3", new_object->three_);
@ -242,7 +242,7 @@ TEST(ArenaTest, CreateWithEightConstructorArguments) {
const MustBeConstructedWithOneThroughEight* new_object =
Arena::Create<MustBeConstructedWithOneThroughEight>(
&arena, 1, "2", three, &four, 5, "6", seven, eight);
EXPECT_TRUE(new_object != NULL);
EXPECT_TRUE(new_object != nullptr);
ASSERT_EQ(1, new_object->one_);
ASSERT_STREQ("2", new_object->two_);
ASSERT_EQ("3", new_object->three_);
@ -504,7 +504,7 @@ TEST(ArenaTest, ReleaseMessage) {
TestAllTypes::NestedMessage* released_null =
arena_message->release_optional_nested_message();
EXPECT_EQ(NULL, released_null);
EXPECT_EQ(nullptr, released_null);
}
TEST(ArenaTest, SetAllocatedString) {
@ -605,8 +605,8 @@ TEST(ArenaTest, SwapBetweenArenaAndNonArenaUsingReflection) {
}
TEST(ArenaTest, ReleaseFromArenaMessageMakesCopy) {
TestAllTypes::NestedMessage* nested_msg = NULL;
std::string* nested_string = NULL;
TestAllTypes::NestedMessage* nested_msg = nullptr;
std::string* nested_string = nullptr;
{
Arena arena;
TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
@ -623,7 +623,7 @@ TEST(ArenaTest, ReleaseFromArenaMessageMakesCopy) {
#if PROTOBUF_RTTI
TEST(ArenaTest, ReleaseFromArenaMessageUsingReflectionMakesCopy) {
TestAllTypes::NestedMessage* nested_msg = NULL;
TestAllTypes::NestedMessage* nested_msg = nullptr;
// Note: no string: reflection API only supports releasing submessages.
{
Arena arena;
@ -1098,7 +1098,7 @@ TEST(ArenaTest, ArenaOneofReflection) {
EXPECT_TRUE(refl->HasOneof(*message, oneof));
submsg = refl->ReleaseMessage(message, msg_field);
EXPECT_FALSE(refl->HasOneof(*message, oneof));
EXPECT_TRUE(submsg->GetArena() == NULL);
EXPECT_TRUE(submsg->GetArena() == nullptr);
delete submsg;
}
@ -1111,7 +1111,7 @@ void TestSwapRepeatedField(Arena* arena1, Arena* arena2) {
TestAllTypes* t = Arena::CreateMessage<TestAllTypes>(arena1);
t->set_optional_string("field1");
t->set_optional_int32(i);
if (arena1 != NULL) {
if (arena1 != nullptr) {
field1.UnsafeArenaAddAllocated(t);
} else {
field1.AddAllocated(t);
@ -1121,7 +1121,7 @@ void TestSwapRepeatedField(Arena* arena1, Arena* arena2) {
TestAllTypes* t = Arena::CreateMessage<TestAllTypes>(arena2);
t->set_optional_string("field2");
t->set_optional_int32(i);
if (arena2 != NULL) {
if (arena2 != nullptr) {
field2.UnsafeArenaAddAllocated(t);
} else {
field2.AddAllocated(t);
@ -1154,12 +1154,12 @@ TEST(ArenaTest, SwapRepeatedFieldWithDifferentArenas) {
TEST(ArenaTest, SwapRepeatedFieldWithNoArenaOnRightHandSide) {
Arena arena;
TestSwapRepeatedField(&arena, NULL);
TestSwapRepeatedField(&arena, nullptr);
}
TEST(ArenaTest, SwapRepeatedFieldWithNoArenaOnLeftHandSide) {
Arena arena;
TestSwapRepeatedField(NULL, &arena);
TestSwapRepeatedField(nullptr, &arena);
}
TEST(ArenaTest, ExtensionsOnArena) {
@ -1218,11 +1218,11 @@ TEST(ArenaTest, RepeatedFieldOnArena) {
TestAllTypes* extracted_messages[5];
// ExtractSubrange should copy to the heap.
repeated_message.ExtractSubrange(0, 5, extracted_messages);
EXPECT_EQ(NULL, extracted_messages[0]->GetArena());
EXPECT_EQ(nullptr, extracted_messages[0]->GetArena());
// We need to free the heap-allocated messages to prevent a leak.
for (int i = 0; i < 5; i++) {
delete extracted_messages[i];
extracted_messages[i] = NULL;
extracted_messages[i] = nullptr;
}
}
@ -1342,7 +1342,7 @@ TEST(ArenaTest, MessageLiteOnArena) {
{
MessageLite* generic_message = prototype->New(&arena);
EXPECT_TRUE(generic_message != NULL);
EXPECT_TRUE(generic_message != nullptr);
EXPECT_EQ(&arena, generic_message->GetArena());
EXPECT_TRUE(generic_message->ParseFromString(serialized));
TestAllTypes* deserialized = static_cast<TestAllTypes*>(generic_message);
@ -1463,8 +1463,8 @@ TEST(ArenaTest, GetArenaShouldReturnTheArenaForArenaAllocatedMessages) {
TEST(ArenaTest, GetArenaShouldReturnNullForNonArenaAllocatedMessages) {
ArenaMessage message;
const ArenaMessage* const_pointer_to_message = &message;
EXPECT_EQ(NULL, Arena::GetArena(&message));
EXPECT_EQ(NULL, Arena::GetArena(const_pointer_to_message));
EXPECT_EQ(nullptr, Arena::GetArena(&message));
EXPECT_EQ(nullptr, Arena::GetArena(const_pointer_to_message));
}
TEST(ArenaTest, GetArenaShouldReturnNullForNonArenaCompatibleTypes) {

@ -1680,8 +1680,7 @@ CommandLineInterface::InterpretArgument(const std::string& name,
})) {
case google::protobuf::io::win32::ExpandWildcardsResult::kSuccess:
break;
case google::protobuf::io::win32::ExpandWildcardsResult::
kErrorNoMatchingFile:
case google::protobuf::io::win32::ExpandWildcardsResult::kErrorNoMatchingFile:
// Path does not exist, is not a file, or it's longer than MAX_PATH and
// long path handling is disabled.
std::cerr << "Invalid file name pattern or missing input file \""

@ -925,6 +925,13 @@ bool HasLazyFields(const FileDescriptor* file, const Options& options,
bool ShouldSplit(const Descriptor*, const Options&) { return false; }
bool ShouldSplit(const FieldDescriptor*, const Options&) { return false; }
bool ShouldForceAllocationOnConstruction(const Descriptor* desc,
const Options& options) {
(void)desc;
(void)options;
return false;
}
static bool HasRepeatedFields(const Descriptor* descriptor) {
for (int i = 0; i < descriptor->field_count(); ++i) {
if (descriptor->field(i)->label() == FieldDescriptor::LABEL_REPEATED) {

@ -379,6 +379,11 @@ bool ShouldSplit(const Descriptor* desc, const Options& options);
// Is the given field being split out?
bool ShouldSplit(const FieldDescriptor* field, const Options& options);
// Should we generate code that force creating an allocation in the constructor
// of the given message?
bool ShouldForceAllocationOnConstruction(const Descriptor* desc,
const Options& options);
inline bool IsFieldUsed(const FieldDescriptor* /* field */,
const Options& /* options */) {
return true;

@ -1269,9 +1269,9 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) {
GenerateSingularFieldHasBits(field, format);
}
if (!IsCrossFileMaybeMap(field)) {
GenerateFieldClear(field, true, format);
}
if (!IsCrossFileMaybeMap(field)) {
GenerateFieldClear(field, true, format);
}
// Generate type-specific accessors.
if (!IsFieldStripped(field, options_)) {
@ -2483,6 +2483,13 @@ void MessageGenerator::GenerateSharedConstructorCode(io::Printer* printer) {
field_generators_.get(field).GenerateConstructorCode(printer);
}
if (ShouldForceAllocationOnConstruction(descriptor_, options_)) {
format(
"#ifdef PROTOBUF_FORCE_ALLOCATION_ON_CONSTRUCTION\n"
"$mutable_unknown_fields$;\n"
"#endif // PROTOBUF_FORCE_ALLOCATION_ON_CONSTRUCTION\n");
}
for (auto oneof : OneOfRange(descriptor_)) {
format("clear_has_$1$();\n", oneof->name());
}
@ -2722,6 +2729,13 @@ void MessageGenerator::GenerateCopyConstructorBody(io::Printer* printer) const {
" static_cast<size_t>(reinterpret_cast<char*>(&$last$) -\n"
" reinterpret_cast<char*>(&$first$)) + sizeof($last$));\n";
if (ShouldForceAllocationOnConstruction(descriptor_, options_)) {
format(
"#ifdef PROTOBUF_FORCE_ALLOCATION_ON_CONSTRUCTION\n"
"$mutable_unknown_fields$;\n"
"#endif // PROTOBUF_FORCE_ALLOCATION_ON_CONSTRUCTION\n");
}
for (size_t i = 0; i < optimized_order_.size(); ++i) {
const FieldDescriptor* field = optimized_order_[i];
if (ShouldSplit(field, options_)) {

@ -46,6 +46,7 @@
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/io/io_win32.h>
#include <google/protobuf/message.h>
namespace google {
@ -113,7 +114,7 @@ void Subprocess::Start(const std::string& program, SearchMode search_mode) {
}
// Setup STARTUPINFO to redirect handles.
STARTUPINFOA startup_info;
STARTUPINFOW startup_info;
ZeroMemory(&startup_info, sizeof(startup_info));
startup_info.cb = sizeof(startup_info);
startup_info.dwFlags = STARTF_USESTDHANDLES;
@ -125,17 +126,30 @@ void Subprocess::Start(const std::string& program, SearchMode search_mode) {
GOOGLE_LOG(FATAL) << "GetStdHandle: " << Win32ErrorMessage(GetLastError());
}
// get wide string version of program as the path may contain non-ascii characters
std::wstring wprogram;
if (!io::win32::strings::utf8_to_wcs(program.c_str(), &wprogram)) {
GOOGLE_LOG(FATAL) << "utf8_to_wcs: " << Win32ErrorMessage(GetLastError());
}
// Invoking cmd.exe allows for '.bat' files from the path as well as '.exe'.
std::string command_line = "cmd.exe /c \"" + program + "\"";
// get wide string version of command line as the path may contain non-ascii characters
std::wstring wcommand_line;
if (!io::win32::strings::utf8_to_wcs(command_line.c_str(), &wcommand_line)) {
GOOGLE_LOG(FATAL) << "utf8_to_wcs: " << Win32ErrorMessage(GetLastError());
}
// Using a malloc'ed string because CreateProcess() can mutate its second
// parameter.
char* command_line =
portable_strdup(("cmd.exe /c \"" + program + "\"").c_str());
wchar_t *wcommand_line_copy = _wcsdup(wcommand_line.c_str());
// Create the process.
PROCESS_INFORMATION process_info;
if (CreateProcessA((search_mode == SEARCH_PATH) ? nullptr : program.c_str(),
(search_mode == SEARCH_PATH) ? command_line : nullptr,
if (CreateProcessW((search_mode == SEARCH_PATH) ? nullptr : wprogram.c_str(),
(search_mode == SEARCH_PATH) ? wcommand_line_copy : NULL,
nullptr, // process security attributes
nullptr, // thread security attributes
TRUE, // inherit handles?
@ -155,7 +169,7 @@ void Subprocess::Start(const std::string& program, SearchMode search_mode) {
CloseHandleOrDie(stdin_pipe_read);
CloseHandleOrDie(stdout_pipe_write);
free(command_line);
free(wcommand_line_copy);
}
bool Subprocess::Communicate(const Message& input, Message* output,

@ -32,6 +32,7 @@
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_IMPL_H__
#include <cstdint>
#include <cstdlib>
#include <type_traits>
#include <google/protobuf/port.h>
@ -268,11 +269,11 @@ enum FieldType : uint16_t {
#ifndef NDEBUG
template <size_t align>
#ifndef _MSC_VER
[[noreturn]]
#endif
void AlignFail(uintptr_t address) {
GOOGLE_LOG(FATAL) << "Unaligned (" << align << ") access at " << address;
// Explicit abort to let compilers know this function does not return
abort();
}
extern template void AlignFail<4>(uintptr_t);

@ -680,7 +680,7 @@ class PROTOBUF_EXPORT EpsCopyOutputStream {
if (PROTOBUF_PREDICT_FALSE(end_ - ptr < size)) {
return WriteRawFallback(data, size, ptr);
}
std::memcpy(ptr, data, size);
std::memcpy(ptr, data, static_cast<unsigned int>(size));
return ptr + size;
}
// Writes the buffer specified by data, size to the stream. Possibly by
@ -1776,7 +1776,7 @@ inline void CodedOutputStream::WriteRawMaybeAliased(const void* data,
inline uint8_t* CodedOutputStream::WriteRawToArray(const void* data, int size,
uint8_t* target) {
memcpy(target, data, size);
memcpy(target, data, static_cast<unsigned int>(size));
return target + size;
}

@ -379,6 +379,7 @@ class Map {
public:
using key_type = Key;
using mapped_type = T;
using init_type = std::pair<Key, T>;
using value_type = MapPair<Key, T>;
using pointer = value_type*;
@ -421,6 +422,22 @@ class Map {
~Map() {}
private:
template <typename P>
struct SameAsElementReference
: std::is_same<typename std::remove_cv<
typename std::remove_reference<reference>::type>::type,
typename std::remove_cv<
typename std::remove_reference<P>::type>::type> {};
template <class P>
using RequiresInsertable =
typename std::enable_if<std::is_convertible<P, init_type>::value ||
SameAsElementReference<P>::value,
int>::type;
template <class P>
using RequiresNotInit =
typename std::enable_if<!std::is_same<P, init_type>::value, int>::type;
using Allocator = internal::MapAllocator<void*>;
// InnerMap is a generic hash-based map. It doesn't contain any
@ -1270,7 +1287,6 @@ class Map {
const_iterator cbegin() const { return begin(); }
const_iterator cend() const { return end(); }
// Capacity
size_type size() const { return elements_.size(); }
bool empty() const { return size() == 0; }
@ -1351,15 +1367,17 @@ class Map {
elements_.try_emplace(std::forward<K>(k), std::forward<Args>(args)...);
return std::pair<iterator, bool>(iterator(p.first), p.second);
}
std::pair<iterator, bool> insert(const value_type& value) {
return try_emplace(value.first, value.second);
std::pair<iterator, bool> insert(init_type&& value) {
return try_emplace(std::move(value.first), std::move(value.second));
}
std::pair<iterator, bool> insert(value_type&& value) {
return try_emplace(value.first, std::move(value.second));
template <typename P, RequiresInsertable<P> = 0>
std::pair<iterator, bool> insert(P&& value) {
return try_emplace(std::forward<P>(value).first,
std::forward<P>(value).second);
}
template <typename... Args>
std::pair<iterator, bool> emplace(Args&&... args) {
return insert(value_type(std::forward<Args>(args)...));
return EmplaceInternal(Rank0{}, std::forward<Args>(args)...);
}
template <class InputIt>
void insert(InputIt first, InputIt last) {
@ -1368,7 +1386,12 @@ class Map {
try_emplace(pair.first, pair.second);
}
}
void insert(std::initializer_list<value_type> values) {
void insert(std::initializer_list<init_type> values) {
insert(values.begin(), values.end());
}
template <typename P, RequiresNotInit<P> = 0,
RequiresInsertable<const P&> = 0>
void insert(std::initializer_list<P> values) {
insert(values.begin(), values.end());
}
@ -1429,6 +1452,23 @@ class Map {
}
private:
struct Rank1 {};
struct Rank0 : Rank1 {};
// We try to construct `init_type` from `Args` with a fall back to
// `value_type`. The latter is less desired as it unconditionally makes a copy
// of `value_type::first`.
template <typename... Args>
auto EmplaceInternal(Rank0, Args&&... args) ->
typename std::enable_if<std::is_constructible<init_type, Args...>::value,
std::pair<iterator, bool>>::type {
return insert(init_type(std::forward<Args>(args)...));
}
template <typename... Args>
std::pair<iterator, bool> EmplaceInternal(Rank1, Args&&... args) {
return insert(value_type(std::forward<Args>(args)...));
}
Arena* arena() const { return elements_.arena(); }
InnerMap elements_;

@ -737,6 +737,47 @@ TEST_F(MapImplTest, InsertSingleRValue) {
EXPECT_FALSE(result2.second);
}
TEST_F(MapImplTest, InsertSingleBraceInitList) {
int32_t key = 0;
int32_t value1 = 100;
int32_t value2 = 101;
// Insert a non-existing key.
auto result1 = map_.insert({key, value1});
ExpectSingleElement(key, value1);
auto it1 = result1.first;
EXPECT_EQ(key, it1->first);
EXPECT_EQ(value1, it1->second);
EXPECT_TRUE(result1.second);
// Insert an existing key.
auto result2 = map_.insert({key, value2});
ExpectSingleElement(key, value1);
auto it2 = result2.first;
EXPECT_TRUE(it1 == it2);
EXPECT_FALSE(result2.second);
}
TEST_F(MapImplTest, InsertSingleBraceInitListTypeMismatch) {
int32_t key = 0;
int32_t value1 = 100;
int32_t value2 = 101;
Map<int64_t, int64_t> m;
// Insert a non-existing key.
auto result1 = m.insert({key, value1});
EXPECT_TRUE(result1.second);
// Insert an existing key.
auto result2 = m.insert({key, value2});
EXPECT_FALSE(result2.second);
EXPECT_TRUE(result1.first == result2.first);
}
TEST_F(MapImplTest, TryEmplace) {
using ::testing::Pair;
using ::testing::UnorderedElementsAre;
@ -769,6 +810,20 @@ TEST_F(MapImplTest, Emplace) {
m, UnorderedElementsAre(Pair(1, "one"), Pair(2, "two"), Pair(42, "aaa")));
}
TEST_F(MapImplTest, EmplaceKeyOnly) {
using ::testing::Pair;
using ::testing::UnorderedElementsAre;
Map<int32_t, std::string> m;
m.emplace(1);
EXPECT_EQ(m.size(), 1);
const int32_t key = 42;
m.emplace(key);
EXPECT_THAT(m, UnorderedElementsAre(Pair(1, ""), Pair(42, "")));
}
struct CountedInstance {
CountedInstance() { ++num_created; }
CountedInstance(const CountedInstance&) : CountedInstance() {}

@ -191,6 +191,7 @@
#define PROTOBUF_FUTURE_REMOVE_CLEARED_API 1
// Used to escape C++20 keywords.
// TODO(mkruskal): ping b/238664698 when this lands in opensource.
// Owner: mkruskal@
#define PROTOBUF_FUTURE_CPP20_KEYWORDS 1
#else
@ -559,6 +560,10 @@
#error PROTOBUF_FORCE_COPY_DEFAULT_STRING was previously defined
#endif
#ifdef PROTOBUF_FORCE_ALLOCATION_ON_CONSTRUCTION
#error PROTOBUF_FORCE_ALLOCATION_ON_CONSTRUCTION was previously defined
#endif
#ifdef PROTOBUF_FALLTHROUGH_INTENDED
#error PROTOBUF_FALLTHROUGH_INTENDED was previously defined
#endif
@ -664,14 +669,15 @@
#ifdef PROTOBUF_CONSTINIT
#error PROTOBUF_CONSTINIT was previously defined
#endif
#if defined(__cpp_constinit)
#if defined(__cpp_constinit) && !defined(_MSC_VER)
#define PROTOBUF_CONSTINIT constinit
#define PROTOBUF_CONSTEXPR constexpr
// Some older Clang versions incorrectly raise an error about
// constant-initializing weak default instance pointers. Versions 12.0 and
// higher seem to work, except that XCode 12.5.1 shows the error even though it
// uses Clang 12.0.5.
#elif __has_cpp_attribute(clang::require_constant_initialization) && \
// Clang-cl on Windows raises error also.
#elif !defined(_MSC_VER) && __has_cpp_attribute(clang::require_constant_initialization) && \
((defined(__APPLE__) && __clang_major__ >= 13) || \
(!defined(__APPLE__) && __clang_major__ >= 12))
#define PROTOBUF_CONSTINIT [[clang::require_constant_initialization]]
@ -679,6 +685,10 @@
#elif PROTOBUF_GNUC_MIN(12, 2)
#define PROTOBUF_CONSTINIT __constinit
#define PROTOBUF_CONSTEXPR constexpr
// MSVC 17 currently seems to raise an error about constant-initialized pointers.
#elif defined(_MSC_VER) && _MSC_VER >= 1930
#define PROTOBUF_CONSTINIT
#define PROTOBUF_CONSTEXPR constexpr
#else
#define PROTOBUF_CONSTINIT
#define PROTOBUF_CONSTEXPR

@ -75,6 +75,7 @@
#undef PROTOBUF_FORCE_RESET_IN_CLEAR
#undef PROTOBUF_FUZZ_MESSAGE_SPACE_USED_LONG
#undef PROTOBUF_FORCE_COPY_DEFAULT_STRING
#undef PROTOBUF_FORCE_ALLOCATION_ON_CONSTRUCTION
#undef PROTOBUF_NAMESPACE_OPEN
#undef PROTOBUF_NAMESPACE_CLOSE
#undef PROTOBUF_UNUSED

@ -311,6 +311,7 @@ class RepeatedField final {
// This is public due to it being called by generated code.
inline void InternalSwap(RepeatedField* other);
private:
template <typename T> friend class Arena::InternalHelper;
@ -338,7 +339,7 @@ class RepeatedField final {
// current_size_. This function is intended to be the only place where
// current_size_ is modified.
inline int ExchangeCurrentSize(int new_size) {
int prev_size = current_size_;
const int prev_size = current_size_;
current_size_ = new_size;
return prev_size;
}
@ -355,6 +356,7 @@ class RepeatedField final {
}
};
// If total_size_ == 0 this points to an Arena otherwise it points to the
// elements member of a Rep struct. Using this invariant allows the storage of
// the arena pointer without an extra allocation in the constructor.
@ -471,7 +473,7 @@ class RepeatedField final {
void Add(Element val) {
if (index_ == capacity_) {
repeated_field_->ExchangeCurrentSize(index_);
repeated_field_->current_size_ = index_;
repeated_field_->Reserve(index_ + 1);
capacity_ = repeated_field_->total_size_;
buffer_ = repeated_field_->unsafe_elements();

@ -118,7 +118,7 @@ cc_library(
hdrs = ["zero_copy_sink.h"],
copts = COPTS,
strip_include_prefix = "/src",
visibility = ["//visibility:private"],
visibility = ["//pkg:__pkg__"],
deps = [
"//src/google/protobuf",
"//src/google/protobuf/io",

@ -93,6 +93,9 @@ typedef JsonPrintOptions JsonOptions;
// Converts from protobuf message to JSON and appends it to |output|. This is a
// simple wrapper of BinaryToJsonString(). It will use the DescriptorPool of the
// passed-in message to resolve Any types.
//
// Please note that non-OK statuses are not a stable output of this API and
// subject to change without notice.
PROTOBUF_EXPORT util::Status MessageToJsonString(const Message& message,
std::string* output,
const JsonOptions& options);
@ -105,6 +108,9 @@ inline util::Status MessageToJsonString(const Message& message,
// Converts from JSON to protobuf message. This is a simple wrapper of
// JsonStringToBinary(). It will use the DescriptorPool of the passed-in
// message to resolve Any types.
//
// Please note that non-OK statuses are not a stable output of this API and
// subject to change without notice.
PROTOBUF_EXPORT util::Status JsonStringToMessage(
StringPiece input, Message* message, const JsonParseOptions& options);
@ -119,6 +125,9 @@ inline util::Status JsonStringToMessage(StringPiece input,
// 2. input is not valid protobuf wire format, or conflicts with the type
// information returned by TypeResolver.
// Note that unknown fields will be discarded silently.
//
// Please note that non-OK statuses are not a stable output of this API and
// subject to change without notice.
PROTOBUF_EXPORT util::Status BinaryToJsonStream(
TypeResolver* resolver, const std::string& type_url,
io::ZeroCopyInputStream* binary_input,
@ -150,6 +159,9 @@ inline util::Status BinaryToJsonString(TypeResolver* resolver,
// 1. TypeResolver fails to resolve a type.
// 2. input is not valid JSON format, or conflicts with the type
// information returned by TypeResolver.
//
// Please note that non-OK statuses are not a stable output of this API and
// subject to change without notice.
PROTOBUF_EXPORT util::Status JsonToBinaryStream(
TypeResolver* resolver, const std::string& type_url,
io::ZeroCopyInputStream* json_input,

@ -539,6 +539,13 @@ TEST_P(JsonTest, TestParseIgnoreUnknownFields) {
JsonParseOptions options;
options.ignore_unknown_fields = true;
EXPECT_OK(ToProto<TestMessage>(R"({"unknownName":0})", options));
TestMessage m;
m.GetReflection()->MutableUnknownFields(&m)->AddFixed32(9001, 9001);
m.GetReflection()->MutableUnknownFields(&m)->AddFixed64(9001, 9001);
m.GetReflection()->MutableUnknownFields(&m)->AddVarint(9001, 9001);
m.GetReflection()->MutableUnknownFields(&m)->AddLengthDelimited(9001, "9001");
EXPECT_THAT(ToJson(m), IsOkAndHolds("{}"));
}
TEST_P(JsonTest, TestParseErrors) {

@ -1,8 +0,0 @@
#!/bin/bash -u
# This script generates file lists from Bazel, e.g., for cmake.
set -e
bazel build //pkg:gen_src_file_lists
cp -v bazel-bin/pkg/src_file_lists.cmake src/file_lists.cmake
Loading…
Cancel
Save