PROTOBUF_SYNC_PIPER
pull/10233/head
theodorerose 3 years ago
commit 02df2a7dad
  1. 9
      CHANGES.txt
  2. 1
      Makefile.am
  3. 2
      conformance/failure_list_cpp.txt
  4. 299
      csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto2.cs
  5. BIN
      csharp/src/Google.Protobuf.Test/testprotos.pb
  6. 306
      csharp/src/Google.Protobuf/Reflection/Descriptor.cs
  7. 1
      java/BUILD.bazel
  8. 2
      java/protoc/pom.xml
  9. 5
      java/util/pom_template.xml
  10. 3
      java/util/src/main/java/com/google/protobuf/util/Timestamps.java
  11. 7
      java/util/src/test/java/com/google/protobuf/util/TimestampsTest.java
  12. 6
      kokoro/linux/dockerfile/test/php_32bit/Dockerfile
  13. 1
      php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php
  14. 56
      php/src/Google/Protobuf/Internal/FileDescriptorProto.php
  15. 4
      protobuf_deps.bzl
  16. 55
      protoc-artifacts/Dockerfile
  17. 146
      protoc-artifacts/README.md
  18. 294
      protoc-artifacts/build-protoc.sh
  19. 120
      protoc-artifacts/build-zip.sh
  20. 25
      python/google/protobuf/internal/descriptor_test.py
  21. 4
      src/google/protobuf/arena.cc
  22. 12
      src/google/protobuf/arena_impl.h
  23. 82
      src/google/protobuf/compiler/cpp/enum.cc
  24. 5
      src/google/protobuf/compiler/cpp/helpers.cc
  25. 2
      src/google/protobuf/compiler/cpp/helpers.h
  26. 67
      src/google/protobuf/compiler/cpp/message.cc
  27. 3
      src/google/protobuf/compiler/cpp/options.h
  28. 95
      src/google/protobuf/compiler/cpp/padding_optimizer.cc
  29. 28
      src/google/protobuf/compiler/cpp/parse_function_generator.cc
  30. 4
      src/google/protobuf/compiler/java/doc_comment.cc
  31. 2
      src/google/protobuf/compiler/objectivec/objectivec_enum.cc
  32. 5
      src/google/protobuf/compiler/plugin.pb.cc
  33. 4
      src/google/protobuf/compiler/plugin.pb.h
  34. 142
      src/google/protobuf/descriptor.pb.cc
  35. 129
      src/google/protobuf/descriptor.pb.h
  36. 14
      src/google/protobuf/descriptor.proto
  37. 27
      src/google/protobuf/generated_message_reflection.cc
  38. 24
      src/google/protobuf/generated_message_reflection.h
  39. 6
      src/google/protobuf/generated_message_tctable_impl.h
  40. 8
      src/google/protobuf/generated_message_tctable_lite.cc
  41. 2
      src/google/protobuf/port_def.inc
  42. 1
      src/google/protobuf/port_undef.inc
  43. 2
      src/google/protobuf/repeated_field.h
  44. 2
      src/google/protobuf/repeated_ptr_field.h
  45. 5
      src/google/protobuf/struct.pb.cc
  46. 4
      src/google/protobuf/struct.pb.h
  47. 15
      src/google/protobuf/type.pb.cc
  48. 12
      src/google/protobuf/type.pb.h
  49. 27
      src/google/protobuf/util/BUILD.bazel
  50. 1
      src/google/protobuf/util/json_format_proto3.proto
  51. 1
      src/google/protobuf/util/json_util.cc
  52. 305
      src/google/protobuf/util/json_util_test.cc

@ -1,3 +1,12 @@
2022-07-01 Unreleased version
* Add TransferAllMessages() util function
* Break ZeroCopyOutputByteSink into its own file.
* Explicitly instantiate InternalMetadata members at UnknownFieldSet.
* Support kdoc for Kotlin
* Delete unused function: IsProto3Field.
* Add C++20 keywords guarded by PROTOBUF_FUTURE_CPP20_KEYWORDS
* Escape Kotlin keywords in package names in proto generated code
* Fix StrAppend crashing on empty strings.
2022-06-27 Unreleased version
* Handle reflection for message splitting.

@ -590,6 +590,7 @@ java_EXTRA_DIST=
java/lite/src/test/java/com/google/protobuf/LiteTest.java \
java/BUILD.bazel \
java/pom.xml \
java/protoc/pom.xml \
java/util/BUILD.bazel \
java/util/pom.xml \
java/util/pom_template.xml \

@ -12,8 +12,6 @@ Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
Recommended.FieldMaskTooManyUnderscore.JsonOutput
Recommended.Proto3.JsonInput.BoolFieldDoubleQuotedFalse
Recommended.Proto3.JsonInput.BoolFieldDoubleQuotedTrue
Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput
Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput
Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter
Recommended.Proto3.JsonInput.FieldNameDuplicate
Recommended.Proto3.JsonInput.FieldNameDuplicateDifferentCasing1

@ -213,12 +213,13 @@ namespace ProtobufTestMessages.Proto2 {
"dGlvbmFsX2Jvb2wY7gcgASgIEhcKDnJlcGVhdGVkX2ludDMyGPMHIAMoBRoa",
"Cg1PcHRpb25hbEdyb3VwEgkKAWEYASABKAUiFgoUTnVsbEh5cG90aGVzaXNQ",
"cm90bzIiLwoORW51bU9ubHlQcm90bzIiHQoEQm9vbBIKCgZrRmFsc2UQABIJ",
"CgVrVHJ1ZRABIh8KD09uZVN0cmluZ1Byb3RvMhIMCgRkYXRhGAEgASgJKkYK",
"EUZvcmVpZ25FbnVtUHJvdG8yEg8KC0ZPUkVJR05fRk9PEAASDwoLRk9SRUlH",
"Tl9CQVIQARIPCgtGT1JFSUdOX0JBWhACOkoKD2V4dGVuc2lvbl9pbnQzMhIx",
"LnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMucHJvdG8yLlRlc3RBbGxUeXBlc1By",
"b3RvMhh4IAEoBUIvCihjb20uZ29vZ2xlLnByb3RvYnVmX3Rlc3RfbWVzc2Fn",
"ZXMucHJvdG8ySAH4AQE="));
"CgVrVHJ1ZRABIh8KD09uZVN0cmluZ1Byb3RvMhIMCgRkYXRhGAEgASgJIkYK",
"EVByb3RvV2l0aEtleXdvcmRzEg4KBmlubGluZRgBIAEoBRIPCgdjb25jZXB0",
"GAIgASgJEhAKCHJlcXVpcmVzGAMgAygJKkYKEUZvcmVpZ25FbnVtUHJvdG8y",
"Eg8KC0ZPUkVJR05fRk9PEAASDwoLRk9SRUlHTl9CQVIQARIPCgtGT1JFSUdO",
"X0JBWhACOkoKD2V4dGVuc2lvbl9pbnQzMhIxLnByb3RvYnVmX3Rlc3RfbWVz",
"c2FnZXMucHJvdG8yLlRlc3RBbGxUeXBlc1Byb3RvMhh4IAEoBUIvCihjb20u",
"Z29vZ2xlLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMucHJvdG8ySAH4AQE="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::ProtobufTestMessages.Proto2.ForeignEnumProto2), }, new pb::Extension[] { TestMessagesProto2Extensions.ExtensionInt32 }, new pbr::GeneratedClrTypeInfo[] {
@ -231,7 +232,8 @@ namespace ProtobufTestMessages.Proto2 {
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes), global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes.Parser, new[]{ "OptionalInt32", "OptionalString", "NestedMessage", "OptionalGroup", "OptionalBool", "RepeatedInt32" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes.Types.OptionalGroup), global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes.Types.OptionalGroup.Parser, new[]{ "A" }, null, null, null, null)}),
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.NullHypothesisProto2), global::ProtobufTestMessages.Proto2.NullHypothesisProto2.Parser, null, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.EnumOnlyProto2), global::ProtobufTestMessages.Proto2.EnumOnlyProto2.Parser, null, null, new[]{ typeof(global::ProtobufTestMessages.Proto2.EnumOnlyProto2.Types.Bool) }, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.OneStringProto2), global::ProtobufTestMessages.Proto2.OneStringProto2.Parser, new[]{ "Data" }, null, null, null, null)
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.OneStringProto2), global::ProtobufTestMessages.Proto2.OneStringProto2.Parser, new[]{ "Data" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.ProtoWithKeywords), global::ProtobufTestMessages.Proto2.ProtoWithKeywords.Parser, new[]{ "Inline", "Concept", "Requires" }, null, null, null, null)
}));
}
#endregion
@ -8300,6 +8302,289 @@ namespace ProtobufTestMessages.Proto2 {
}
public sealed partial class ProtoWithKeywords : pb::IMessage<ProtoWithKeywords>
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
, pb::IBufferMessage
#endif
{
private static readonly pb::MessageParser<ProtoWithKeywords> _parser = new pb::MessageParser<ProtoWithKeywords>(() => new ProtoWithKeywords());
private pb::UnknownFieldSet _unknownFields;
private int _hasBits0;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public static pb::MessageParser<ProtoWithKeywords> Parser { get { return _parser; } }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public static pbr::MessageDescriptor Descriptor {
get { return global::ProtobufTestMessages.Proto2.TestMessagesProto2Reflection.Descriptor.MessageTypes[6]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public ProtoWithKeywords() {
OnConstruction();
}
partial void OnConstruction();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public ProtoWithKeywords(ProtoWithKeywords other) : this() {
_hasBits0 = other._hasBits0;
inline_ = other.inline_;
concept_ = other.concept_;
requires_ = other.requires_.Clone();
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public ProtoWithKeywords Clone() {
return new ProtoWithKeywords(this);
}
/// <summary>Field number for the "inline" field.</summary>
public const int InlineFieldNumber = 1;
private readonly static int InlineDefaultValue = 0;
private int inline_;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public int Inline {
get { if ((_hasBits0 & 1) != 0) { return inline_; } else { return InlineDefaultValue; } }
set {
_hasBits0 |= 1;
inline_ = value;
}
}
/// <summary>Gets whether the "inline" field is set</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public bool HasInline {
get { return (_hasBits0 & 1) != 0; }
}
/// <summary>Clears the value of the "inline" field</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void ClearInline() {
_hasBits0 &= ~1;
}
/// <summary>Field number for the "concept" field.</summary>
public const int ConceptFieldNumber = 2;
private readonly static string ConceptDefaultValue = "";
private string concept_;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public string Concept {
get { return concept_ ?? ConceptDefaultValue; }
set {
concept_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Gets whether the "concept" field is set</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public bool HasConcept {
get { return concept_ != null; }
}
/// <summary>Clears the value of the "concept" field</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void ClearConcept() {
concept_ = null;
}
/// <summary>Field number for the "requires" field.</summary>
public const int RequiresFieldNumber = 3;
private static readonly pb::FieldCodec<string> _repeated_requires_codec
= pb::FieldCodec.ForString(26);
private readonly pbc::RepeatedField<string> requires_ = new pbc::RepeatedField<string>();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public pbc::RepeatedField<string> Requires {
get { return requires_; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public override bool Equals(object other) {
return Equals(other as ProtoWithKeywords);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public bool Equals(ProtoWithKeywords other) {
if (ReferenceEquals(other, null)) {
return false;
}
if (ReferenceEquals(other, this)) {
return true;
}
if (Inline != other.Inline) return false;
if (Concept != other.Concept) return false;
if(!requires_.Equals(other.requires_)) return false;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public override int GetHashCode() {
int hash = 1;
if (HasInline) hash ^= Inline.GetHashCode();
if (HasConcept) hash ^= Concept.GetHashCode();
hash ^= requires_.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public override string ToString() {
return pb::JsonFormatter.ToDiagnosticString(this);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (HasInline) {
output.WriteRawTag(8);
output.WriteInt32(Inline);
}
if (HasConcept) {
output.WriteRawTag(18);
output.WriteString(Concept);
}
requires_.WriteTo(output, _repeated_requires_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (HasInline) {
output.WriteRawTag(8);
output.WriteInt32(Inline);
}
if (HasConcept) {
output.WriteRawTag(18);
output.WriteString(Concept);
}
requires_.WriteTo(ref output, _repeated_requires_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public int CalculateSize() {
int size = 0;
if (HasInline) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(Inline);
}
if (HasConcept) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Concept);
}
size += requires_.CalculateSize(_repeated_requires_codec);
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void MergeFrom(ProtoWithKeywords other) {
if (other == null) {
return;
}
if (other.HasInline) {
Inline = other.Inline;
}
if (other.HasConcept) {
Concept = other.Concept;
}
requires_.Add(other.requires_);
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void MergeFrom(pb::CodedInputStream input) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
input.ReadRawMessage(this);
#else
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
Inline = input.ReadInt32();
break;
}
case 18: {
Concept = input.ReadString();
break;
}
case 26: {
requires_.AddEntriesFrom(input, _repeated_requires_codec);
break;
}
}
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
break;
case 8: {
Inline = input.ReadInt32();
break;
}
case 18: {
Concept = input.ReadString();
break;
}
case 26: {
requires_.AddEntriesFrom(ref input, _repeated_requires_codec);
break;
}
}
}
}
#endif
}
#endregion
}

@ -26,7 +26,7 @@ namespace Google.Protobuf.Reflection {
string.Concat(
"CiBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90bxIPZ29vZ2xlLnBy",
"b3RvYnVmIkcKEUZpbGVEZXNjcmlwdG9yU2V0EjIKBGZpbGUYASADKAsyJC5n",
"b29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90byLbAwoTRmlsZURl",
"b29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90byLsAwoTRmlsZURl",
"c2NyaXB0b3JQcm90bxIMCgRuYW1lGAEgASgJEg8KB3BhY2thZ2UYAiABKAkS",
"EgoKZGVwZW5kZW5jeRgDIAMoCRIZChFwdWJsaWNfZGVwZW5kZW5jeRgKIAMo",
"BRIXCg93ZWFrX2RlcGVuZGVuY3kYCyADKAUSNgoMbWVzc2FnZV90eXBlGAQg",
@ -37,134 +37,134 @@ namespace Google.Protobuf.Reflection {
"LnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvEi0KB29wdGlvbnMYCCAB",
"KAsyHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMSOQoQc291cmNlX2Nv",
"ZGVfaW5mbxgJIAEoCzIfLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5m",
"bxIOCgZzeW50YXgYDCABKAkiqQUKD0Rlc2NyaXB0b3JQcm90bxIMCgRuYW1l",
"GAEgASgJEjQKBWZpZWxkGAIgAygLMiUuZ29vZ2xlLnByb3RvYnVmLkZpZWxk",
"RGVzY3JpcHRvclByb3RvEjgKCWV4dGVuc2lvbhgGIAMoCzIlLmdvb2dsZS5w",
"cm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90bxI1CgtuZXN0ZWRfdHlwZRgD",
"IAMoCzIgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8SNwoJZW51",
"bV90eXBlGAQgAygLMiQuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9y",
"UHJvdG8SSAoPZXh0ZW5zaW9uX3JhbmdlGAUgAygLMi8uZ29vZ2xlLnByb3Rv",
"YnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZRI5CgpvbmVvZl9k",
"ZWNsGAggAygLMiUuZ29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclBy",
"b3RvEjAKB29wdGlvbnMYByABKAsyHy5nb29nbGUucHJvdG9idWYuTWVzc2Fn",
"ZU9wdGlvbnMSRgoOcmVzZXJ2ZWRfcmFuZ2UYCSADKAsyLi5nb29nbGUucHJv",
"dG9idWYuRGVzY3JpcHRvclByb3RvLlJlc2VydmVkUmFuZ2USFQoNcmVzZXJ2",
"ZWRfbmFtZRgKIAMoCRplCg5FeHRlbnNpb25SYW5nZRINCgVzdGFydBgBIAEo",
"BRILCgNlbmQYAiABKAUSNwoHb3B0aW9ucxgDIAEoCzImLmdvb2dsZS5wcm90",
"b2J1Zi5FeHRlbnNpb25SYW5nZU9wdGlvbnMaKwoNUmVzZXJ2ZWRSYW5nZRIN",
"CgVzdGFydBgBIAEoBRILCgNlbmQYAiABKAUiZwoVRXh0ZW5zaW9uUmFuZ2VP",
"bxIOCgZzeW50YXgYDCABKAkSDwoHZWRpdGlvbhgNIAEoCSKpBQoPRGVzY3Jp",
"cHRvclByb3RvEgwKBG5hbWUYASABKAkSNAoFZmllbGQYAiADKAsyJS5nb29n",
"bGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8SOAoJZXh0ZW5zaW9u",
"GAYgAygLMiUuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3Rv",
"EjUKC25lc3RlZF90eXBlGAMgAygLMiAuZ29vZ2xlLnByb3RvYnVmLkRlc2Ny",
"aXB0b3JQcm90bxI3CgllbnVtX3R5cGUYBCADKAsyJC5nb29nbGUucHJvdG9i",
"dWYuRW51bURlc2NyaXB0b3JQcm90bxJICg9leHRlbnNpb25fcmFuZ2UYBSAD",
"KAsyLy5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lv",
"blJhbmdlEjkKCm9uZW9mX2RlY2wYCCADKAsyJS5nb29nbGUucHJvdG9idWYu",
"T25lb2ZEZXNjcmlwdG9yUHJvdG8SMAoHb3B0aW9ucxgHIAEoCzIfLmdvb2ds",
"ZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxJGCg5yZXNlcnZlZF9yYW5nZRgJ",
"IAMoCzIuLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uUmVzZXJ2",
"ZWRSYW5nZRIVCg1yZXNlcnZlZF9uYW1lGAogAygJGmUKDkV4dGVuc2lvblJh",
"bmdlEg0KBXN0YXJ0GAEgASgFEgsKA2VuZBgCIAEoBRI3CgdvcHRpb25zGAMg",
"ASgLMiYuZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJhbmdlT3B0aW9ucxor",
"Cg1SZXNlcnZlZFJhbmdlEg0KBXN0YXJ0GAEgASgFEgsKA2VuZBgCIAEoBSJn",
"ChVFeHRlbnNpb25SYW5nZU9wdGlvbnMSQwoUdW5pbnRlcnByZXRlZF9vcHRp",
"b24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRp",
"b24qCQjoBxCAgICAAiLVBQoURmllbGREZXNjcmlwdG9yUHJvdG8SDAoEbmFt",
"ZRgBIAEoCRIOCgZudW1iZXIYAyABKAUSOgoFbGFiZWwYBCABKA4yKy5nb29n",
"bGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uTGFiZWwSOAoEdHlw",
"ZRgFIAEoDjIqLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90",
"by5UeXBlEhEKCXR5cGVfbmFtZRgGIAEoCRIQCghleHRlbmRlZRgCIAEoCRIV",
"Cg1kZWZhdWx0X3ZhbHVlGAcgASgJEhMKC29uZW9mX2luZGV4GAkgASgFEhEK",
"CWpzb25fbmFtZRgKIAEoCRIuCgdvcHRpb25zGAggASgLMh0uZ29vZ2xlLnBy",
"b3RvYnVmLkZpZWxkT3B0aW9ucxIXCg9wcm90bzNfb3B0aW9uYWwYESABKAgi",
"tgIKBFR5cGUSDwoLVFlQRV9ET1VCTEUQARIOCgpUWVBFX0ZMT0FUEAISDgoK",
"VFlQRV9JTlQ2NBADEg8KC1RZUEVfVUlOVDY0EAQSDgoKVFlQRV9JTlQzMhAF",
"EhAKDFRZUEVfRklYRUQ2NBAGEhAKDFRZUEVfRklYRUQzMhAHEg0KCVRZUEVf",
"Qk9PTBAIEg8KC1RZUEVfU1RSSU5HEAkSDgoKVFlQRV9HUk9VUBAKEhAKDFRZ",
"UEVfTUVTU0FHRRALEg4KClRZUEVfQllURVMQDBIPCgtUWVBFX1VJTlQzMhAN",
"Eg0KCVRZUEVfRU5VTRAOEhEKDVRZUEVfU0ZJWEVEMzIQDxIRCg1UWVBFX1NG",
"SVhFRDY0EBASDwoLVFlQRV9TSU5UMzIQERIPCgtUWVBFX1NJTlQ2NBASIkMK",
"BUxhYmVsEhIKDkxBQkVMX09QVElPTkFMEAESEgoOTEFCRUxfUkVRVUlSRUQQ",
"AhISCg5MQUJFTF9SRVBFQVRFRBADIlQKFE9uZW9mRGVzY3JpcHRvclByb3Rv",
"EgwKBG5hbWUYASABKAkSLgoHb3B0aW9ucxgCIAEoCzIdLmdvb2dsZS5wcm90",
"b2J1Zi5PbmVvZk9wdGlvbnMipAIKE0VudW1EZXNjcmlwdG9yUHJvdG8SDAoE",
"bmFtZRgBIAEoCRI4CgV2YWx1ZRgCIAMoCzIpLmdvb2dsZS5wcm90b2J1Zi5F",
"bnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8SLQoHb3B0aW9ucxgDIAEoCzIcLmdv",
"b2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucxJOCg5yZXNlcnZlZF9yYW5nZRgE",
"IAMoCzI2Lmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLkVu",
"dW1SZXNlcnZlZFJhbmdlEhUKDXJlc2VydmVkX25hbWUYBSADKAkaLwoRRW51",
"bVJlc2VydmVkUmFuZ2USDQoFc3RhcnQYASABKAUSCwoDZW5kGAIgASgFImwK",
"GEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bxIMCgRuYW1lGAEgASgJEg4KBm51",
"bWJlchgCIAEoBRIyCgdvcHRpb25zGAMgASgLMiEuZ29vZ2xlLnByb3RvYnVm",
"LkVudW1WYWx1ZU9wdGlvbnMikAEKFlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8S",
"DAoEbmFtZRgBIAEoCRI2CgZtZXRob2QYAiADKAsyJi5nb29nbGUucHJvdG9i",
"dWYuTWV0aG9kRGVzY3JpcHRvclByb3RvEjAKB29wdGlvbnMYAyABKAsyHy5n",
"b29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMiwQEKFU1ldGhvZERlc2Ny",
"aXB0b3JQcm90bxIMCgRuYW1lGAEgASgJEhIKCmlucHV0X3R5cGUYAiABKAkS",
"EwoLb3V0cHV0X3R5cGUYAyABKAkSLwoHb3B0aW9ucxgEIAEoCzIeLmdvb2ds",
"ZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zEh8KEGNsaWVudF9zdHJlYW1pbmcY",
"BSABKAg6BWZhbHNlEh8KEHNlcnZlcl9zdHJlYW1pbmcYBiABKAg6BWZhbHNl",
"IqUGCgtGaWxlT3B0aW9ucxIUCgxqYXZhX3BhY2thZ2UYASABKAkSHAoUamF2",
"YV9vdXRlcl9jbGFzc25hbWUYCCABKAkSIgoTamF2YV9tdWx0aXBsZV9maWxl",
"cxgKIAEoCDoFZmFsc2USKQodamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hh",
"c2gYFCABKAhCAhgBEiUKFmphdmFfc3RyaW5nX2NoZWNrX3V0ZjgYGyABKAg6",
"BWZhbHNlEkYKDG9wdGltaXplX2ZvchgJIAEoDjIpLmdvb2dsZS5wcm90b2J1",
"Zi5GaWxlT3B0aW9ucy5PcHRpbWl6ZU1vZGU6BVNQRUVEEhIKCmdvX3BhY2th",
"Z2UYCyABKAkSIgoTY2NfZ2VuZXJpY19zZXJ2aWNlcxgQIAEoCDoFZmFsc2US",
"JAoVamF2YV9nZW5lcmljX3NlcnZpY2VzGBEgASgIOgVmYWxzZRIiChNweV9n",
"ZW5lcmljX3NlcnZpY2VzGBIgASgIOgVmYWxzZRIjChRwaHBfZ2VuZXJpY19z",
"ZXJ2aWNlcxgqIAEoCDoFZmFsc2USGQoKZGVwcmVjYXRlZBgXIAEoCDoFZmFs",
"c2USHgoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoEdHJ1ZRIZChFvYmpjX2Ns",
"YXNzX3ByZWZpeBgkIAEoCRIYChBjc2hhcnBfbmFtZXNwYWNlGCUgASgJEhQK",
"DHN3aWZ0X3ByZWZpeBgnIAEoCRIYChBwaHBfY2xhc3NfcHJlZml4GCggASgJ",
"EhUKDXBocF9uYW1lc3BhY2UYKSABKAkSHgoWcGhwX21ldGFkYXRhX25hbWVz",
"cGFjZRgsIAEoCRIUCgxydWJ5X3BhY2thZ2UYLSABKAkSQwoUdW5pbnRlcnBy",
"ZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJw",
"cmV0ZWRPcHRpb24iOgoMT3B0aW1pemVNb2RlEgkKBVNQRUVEEAESDQoJQ09E",
"RV9TSVpFEAISEAoMTElURV9SVU5USU1FEAMqCQjoBxCAgICAAkoECCYQJyKE",
"AgoOTWVzc2FnZU9wdGlvbnMSJgoXbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQY",
"ASABKAg6BWZhbHNlEi4KH25vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNz",
"b3IYAiABKAg6BWZhbHNlEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlEhEK",
"CW1hcF9lbnRyeRgHIAEoCBJDChR1bmludGVycHJldGVkX29wdGlvbhjnByAD",
"KAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJCOgH",
"EICAgIACSgQIBBAFSgQIBRAGSgQIBhAHSgQICBAJSgQICRAKIr4DCgxGaWVs",
"ZE9wdGlvbnMSOgoFY3R5cGUYASABKA4yIy5nb29nbGUucHJvdG9idWYuRmll",
"bGRPcHRpb25zLkNUeXBlOgZTVFJJTkcSDgoGcGFja2VkGAIgASgIEj8KBmpz",
"dHlwZRgGIAEoDjIkLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuSlNU",
"eXBlOglKU19OT1JNQUwSEwoEbGF6eRgFIAEoCDoFZmFsc2USHgoPdW52ZXJp",
"ZmllZF9sYXp5GA8gASgIOgVmYWxzZRIZCgpkZXByZWNhdGVkGAMgASgIOgVm",
"YWxzZRITCgR3ZWFrGAogASgIOgVmYWxzZRJDChR1bmludGVycHJldGVkX29w",
"dGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9w",
"dGlvbiIvCgVDVHlwZRIKCgZTVFJJTkcQABIICgRDT1JEEAESEAoMU1RSSU5H",
"X1BJRUNFEAIiNQoGSlNUeXBlEg0KCUpTX05PUk1BTBAAEg0KCUpTX1NUUklO",
"RxABEg0KCUpTX05VTUJFUhACKgkI6AcQgICAgAJKBAgEEAUiXgoMT25lb2ZP",
"cHRpb25zEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2ds",
"ZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIi1QUK",
"FEZpZWxkRGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkSDgoGbnVtYmVy",
"GAMgASgFEjoKBWxhYmVsGAQgASgOMisuZ29vZ2xlLnByb3RvYnVmLkZpZWxk",
"RGVzY3JpcHRvclByb3RvLkxhYmVsEjgKBHR5cGUYBSABKA4yKi5nb29nbGUu",
"cHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZRIRCgl0eXBlX25h",
"bWUYBiABKAkSEAoIZXh0ZW5kZWUYAiABKAkSFQoNZGVmYXVsdF92YWx1ZRgH",
"IAEoCRITCgtvbmVvZl9pbmRleBgJIAEoBRIRCglqc29uX25hbWUYCiABKAkS",
"LgoHb3B0aW9ucxgIIAEoCzIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlv",
"bnMSFwoPcHJvdG8zX29wdGlvbmFsGBEgASgIIrYCCgRUeXBlEg8KC1RZUEVf",
"RE9VQkxFEAESDgoKVFlQRV9GTE9BVBACEg4KClRZUEVfSU5UNjQQAxIPCgtU",
"WVBFX1VJTlQ2NBAEEg4KClRZUEVfSU5UMzIQBRIQCgxUWVBFX0ZJWEVENjQQ",
"BhIQCgxUWVBFX0ZJWEVEMzIQBxINCglUWVBFX0JPT0wQCBIPCgtUWVBFX1NU",
"UklORxAJEg4KClRZUEVfR1JPVVAQChIQCgxUWVBFX01FU1NBR0UQCxIOCgpU",
"WVBFX0JZVEVTEAwSDwoLVFlQRV9VSU5UMzIQDRINCglUWVBFX0VOVU0QDhIR",
"Cg1UWVBFX1NGSVhFRDMyEA8SEQoNVFlQRV9TRklYRUQ2NBAQEg8KC1RZUEVf",
"U0lOVDMyEBESDwoLVFlQRV9TSU5UNjQQEiJDCgVMYWJlbBISCg5MQUJFTF9P",
"UFRJT05BTBABEhIKDkxBQkVMX1JFUVVJUkVEEAISEgoOTEFCRUxfUkVQRUFU",
"RUQQAyJUChRPbmVvZkRlc2NyaXB0b3JQcm90bxIMCgRuYW1lGAEgASgJEi4K",
"B29wdGlvbnMYAiABKAsyHS5nb29nbGUucHJvdG9idWYuT25lb2ZPcHRpb25z",
"IqQCChNFbnVtRGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkSOAoFdmFs",
"dWUYAiADKAsyKS5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRv",
"clByb3RvEi0KB29wdGlvbnMYAyABKAsyHC5nb29nbGUucHJvdG9idWYuRW51",
"bU9wdGlvbnMSTgoOcmVzZXJ2ZWRfcmFuZ2UYBCADKAsyNi5nb29nbGUucHJv",
"dG9idWYuRW51bURlc2NyaXB0b3JQcm90by5FbnVtUmVzZXJ2ZWRSYW5nZRIV",
"Cg1yZXNlcnZlZF9uYW1lGAUgAygJGi8KEUVudW1SZXNlcnZlZFJhbmdlEg0K",
"BXN0YXJ0GAEgASgFEgsKA2VuZBgCIAEoBSJsChhFbnVtVmFsdWVEZXNjcmlw",
"dG9yUHJvdG8SDAoEbmFtZRgBIAEoCRIOCgZudW1iZXIYAiABKAUSMgoHb3B0",
"aW9ucxgDIAEoCzIhLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25z",
"IpABChZTZXJ2aWNlRGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkSNgoG",
"bWV0aG9kGAIgAygLMiYuZ29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0",
"b3JQcm90bxIwCgdvcHRpb25zGAMgASgLMh8uZ29vZ2xlLnByb3RvYnVmLlNl",
"cnZpY2VPcHRpb25zIsEBChVNZXRob2REZXNjcmlwdG9yUHJvdG8SDAoEbmFt",
"ZRgBIAEoCRISCgppbnB1dF90eXBlGAIgASgJEhMKC291dHB1dF90eXBlGAMg",
"ASgJEi8KB29wdGlvbnMYBCABKAsyHi5nb29nbGUucHJvdG9idWYuTWV0aG9k",
"T3B0aW9ucxIfChBjbGllbnRfc3RyZWFtaW5nGAUgASgIOgVmYWxzZRIfChBz",
"ZXJ2ZXJfc3RyZWFtaW5nGAYgASgIOgVmYWxzZSKlBgoLRmlsZU9wdGlvbnMS",
"FAoMamF2YV9wYWNrYWdlGAEgASgJEhwKFGphdmFfb3V0ZXJfY2xhc3NuYW1l",
"GAggASgJEiIKE2phdmFfbXVsdGlwbGVfZmlsZXMYCiABKAg6BWZhbHNlEikK",
"HWphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoGBQgASgIQgIYARIlChZq",
"YXZhX3N0cmluZ19jaGVja191dGY4GBsgASgIOgVmYWxzZRJGCgxvcHRpbWl6",
"ZV9mb3IYCSABKA4yKS5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuT3B0",
"aW1pemVNb2RlOgVTUEVFRBISCgpnb19wYWNrYWdlGAsgASgJEiIKE2NjX2dl",
"bmVyaWNfc2VydmljZXMYECABKAg6BWZhbHNlEiQKFWphdmFfZ2VuZXJpY19z",
"ZXJ2aWNlcxgRIAEoCDoFZmFsc2USIgoTcHlfZ2VuZXJpY19zZXJ2aWNlcxgS",
"IAEoCDoFZmFsc2USIwoUcGhwX2dlbmVyaWNfc2VydmljZXMYKiABKAg6BWZh",
"bHNlEhkKCmRlcHJlY2F0ZWQYFyABKAg6BWZhbHNlEh4KEGNjX2VuYWJsZV9h",
"cmVuYXMYHyABKAg6BHRydWUSGQoRb2JqY19jbGFzc19wcmVmaXgYJCABKAkS",
"GAoQY3NoYXJwX25hbWVzcGFjZRglIAEoCRIUCgxzd2lmdF9wcmVmaXgYJyAB",
"KAkSGAoQcGhwX2NsYXNzX3ByZWZpeBgoIAEoCRIVCg1waHBfbmFtZXNwYWNl",
"GCkgASgJEh4KFnBocF9tZXRhZGF0YV9uYW1lc3BhY2UYLCABKAkSFAoMcnVi",
"eV9wYWNrYWdlGC0gASgJEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMo",
"CzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIjoKDE9w",
"dGltaXplTW9kZRIJCgVTUEVFRBABEg0KCUNPREVfU0laRRACEhAKDExJVEVf",
"UlVOVElNRRADKgkI6AcQgICAgAJKBAgmECcihAIKDk1lc3NhZ2VPcHRpb25z",
"EiYKF21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0GAEgASgIOgVmYWxzZRIuCh9u",
"b19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yGAIgASgIOgVmYWxzZRIZ",
"CgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZRIRCgltYXBfZW50cnkYByABKAgS",
"QwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3Rv",
"YnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAkoECAQQBUoECAUQ",
"BkoECAYQB0oECAgQCUoECAkQCiK+AwoMRmllbGRPcHRpb25zEjoKBWN0eXBl",
"GAEgASgOMiMuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5DVHlwZToG",
"U1RSSU5HEg4KBnBhY2tlZBgCIAEoCBI/CgZqc3R5cGUYBiABKA4yJC5nb29n",
"bGUucHJvdG9idWYuRmllbGRPcHRpb25zLkpTVHlwZToJSlNfTk9STUFMEhMK",
"BGxhenkYBSABKAg6BWZhbHNlEh4KD3VudmVyaWZpZWRfbGF6eRgPIAEoCDoF",
"ZmFsc2USGQoKZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2USEwoEd2VhaxgKIAEo",
"CDoFZmFsc2USQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29v",
"Z2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24iLwoFQ1R5cGUSCgoG",
"U1RSSU5HEAASCAoEQ09SRBABEhAKDFNUUklOR19QSUVDRRACIjUKBkpTVHlw",
"ZRINCglKU19OT1JNQUwQABINCglKU19TVFJJTkcQARINCglKU19OVU1CRVIQ",
"AioJCOgHEICAgIACSgQIBBAFIl4KDE9uZW9mT3B0aW9ucxJDChR1bmludGVy",
"cHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRl",
"cnByZXRlZE9wdGlvbioJCOgHEICAgIACIpMBCgtFbnVtT3B0aW9ucxITCgth",
"bGxvd19hbGlhcxgCIAEoCBIZCgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZRJD",
"ChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9i",
"dWYuVW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACSgQIBRAGIn0KEEVu",
"dW1WYWx1ZU9wdGlvbnMSGQoKZGVwcmVjYXRlZBgBIAEoCDoFZmFsc2USQwoU",
"dW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVm",
"LlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiJ7Cg5TZXJ2aWNlT3B0",
"aW9ucxIZCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZRJDChR1bmludGVycHJl",
"dGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnBy",
"ZXRlZE9wdGlvbioJCOgHEICAgIACIq0CCg1NZXRob2RPcHRpb25zEhkKCmRl",
"cHJlY2F0ZWQYISABKAg6BWZhbHNlEl8KEWlkZW1wb3RlbmN5X2xldmVsGCIg",
"ASgOMi8uZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMuSWRlbXBvdGVu",
"Y3lMZXZlbDoTSURFTVBPVEVOQ1lfVU5LTk9XThJDChR1bmludGVycHJldGVk",
"X29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRl",
"ZE9wdGlvbiJQChBJZGVtcG90ZW5jeUxldmVsEhcKE0lERU1QT1RFTkNZX1VO",
"S05PV04QABITCg9OT19TSURFX0VGRkVDVFMQARIOCgpJREVNUE9URU5UEAIq",
"CQjoBxCAgICAAiKeAgoTVW5pbnRlcnByZXRlZE9wdGlvbhI7CgRuYW1lGAIg",
"AygLMi0uZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFt",
"ZVBhcnQSGAoQaWRlbnRpZmllcl92YWx1ZRgDIAEoCRIaChJwb3NpdGl2ZV9p",
"bnRfdmFsdWUYBCABKAQSGgoSbmVnYXRpdmVfaW50X3ZhbHVlGAUgASgDEhQK",
"DGRvdWJsZV92YWx1ZRgGIAEoARIUCgxzdHJpbmdfdmFsdWUYByABKAwSFwoP",
"YWdncmVnYXRlX3ZhbHVlGAggASgJGjMKCE5hbWVQYXJ0EhEKCW5hbWVfcGFy",
"dBgBIAIoCRIUCgxpc19leHRlbnNpb24YAiACKAgi1QEKDlNvdXJjZUNvZGVJ",
"bmZvEjoKCGxvY2F0aW9uGAEgAygLMiguZ29vZ2xlLnByb3RvYnVmLlNvdXJj",
"ZUNvZGVJbmZvLkxvY2F0aW9uGoYBCghMb2NhdGlvbhIQCgRwYXRoGAEgAygF",
"QgIQARIQCgRzcGFuGAIgAygFQgIQARIYChBsZWFkaW5nX2NvbW1lbnRzGAMg",
"ASgJEhkKEXRyYWlsaW5nX2NvbW1lbnRzGAQgASgJEiEKGWxlYWRpbmdfZGV0",
"YWNoZWRfY29tbWVudHMYBiADKAkipwEKEUdlbmVyYXRlZENvZGVJbmZvEkEK",
"CmFubm90YXRpb24YASADKAsyLS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVk",
"Q29kZUluZm8uQW5ub3RhdGlvbhpPCgpBbm5vdGF0aW9uEhAKBHBhdGgYASAD",
"KAVCAhABEhMKC3NvdXJjZV9maWxlGAIgASgJEg0KBWJlZ2luGAMgASgFEgsK",
"A2VuZBgEIAEoBUJ+ChNjb20uZ29vZ2xlLnByb3RvYnVmQhBEZXNjcmlwdG9y",
"UHJvdG9zSAFaLWdvb2dsZS5nb2xhbmcub3JnL3Byb3RvYnVmL3R5cGVzL2Rl",
"c2NyaXB0b3JwYvgBAaICA0dQQqoCGkdvb2dsZS5Qcm90b2J1Zi5SZWZsZWN0",
"aW9u"));
"ZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIikwEK",
"C0VudW1PcHRpb25zEhMKC2FsbG93X2FsaWFzGAIgASgIEhkKCmRlcHJlY2F0",
"ZWQYAyABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMo",
"CzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQ",
"gICAgAJKBAgFEAYifQoQRW51bVZhbHVlT3B0aW9ucxIZCgpkZXByZWNhdGVk",
"GAEgASgIOgVmYWxzZRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsy",
"JC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICA",
"gIACInsKDlNlcnZpY2VPcHRpb25zEhkKCmRlcHJlY2F0ZWQYISABKAg6BWZh",
"bHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5w",
"cm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIirQIKDU1l",
"dGhvZE9wdGlvbnMSGQoKZGVwcmVjYXRlZBghIAEoCDoFZmFsc2USXwoRaWRl",
"bXBvdGVuY3lfbGV2ZWwYIiABKA4yLy5nb29nbGUucHJvdG9idWYuTWV0aG9k",
"T3B0aW9ucy5JZGVtcG90ZW5jeUxldmVsOhNJREVNUE9URU5DWV9VTktOT1dO",
"EkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90",
"b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIlAKEElkZW1wb3RlbmN5TGV2ZWwS",
"FwoTSURFTVBPVEVOQ1lfVU5LTk9XThAAEhMKD05PX1NJREVfRUZGRUNUUxAB",
"Eg4KCklERU1QT1RFTlQQAioJCOgHEICAgIACIp4CChNVbmludGVycHJldGVk",
"T3B0aW9uEjsKBG5hbWUYAiADKAsyLS5nb29nbGUucHJvdG9idWYuVW5pbnRl",
"cnByZXRlZE9wdGlvbi5OYW1lUGFydBIYChBpZGVudGlmaWVyX3ZhbHVlGAMg",
"ASgJEhoKEnBvc2l0aXZlX2ludF92YWx1ZRgEIAEoBBIaChJuZWdhdGl2ZV9p",
"bnRfdmFsdWUYBSABKAMSFAoMZG91YmxlX3ZhbHVlGAYgASgBEhQKDHN0cmlu",
"Z192YWx1ZRgHIAEoDBIXCg9hZ2dyZWdhdGVfdmFsdWUYCCABKAkaMwoITmFt",
"ZVBhcnQSEQoJbmFtZV9wYXJ0GAEgAigJEhQKDGlzX2V4dGVuc2lvbhgCIAIo",
"CCLVAQoOU291cmNlQ29kZUluZm8SOgoIbG9jYXRpb24YASADKAsyKC5nb29n",
"bGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ahgEKCExvY2F0",
"aW9uEhAKBHBhdGgYASADKAVCAhABEhAKBHNwYW4YAiADKAVCAhABEhgKEGxl",
"YWRpbmdfY29tbWVudHMYAyABKAkSGQoRdHJhaWxpbmdfY29tbWVudHMYBCAB",
"KAkSIQoZbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cxgGIAMoCSKnAQoRR2Vu",
"ZXJhdGVkQ29kZUluZm8SQQoKYW5ub3RhdGlvbhgBIAMoCzItLmdvb2dsZS5w",
"cm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uGk8KCkFubm90",
"YXRpb24SEAoEcGF0aBgBIAMoBUICEAESEwoLc291cmNlX2ZpbGUYAiABKAkS",
"DQoFYmVnaW4YAyABKAUSCwoDZW5kGAQgASgFQn4KE2NvbS5nb29nbGUucHJv",
"dG9idWZCEERlc2NyaXB0b3JQcm90b3NIAVotZ29vZ2xlLmdvbGFuZy5vcmcv",
"cHJvdG9idWYvdHlwZXMvZGVzY3JpcHRvcnBi+AEBogIDR1BCqgIaR29vZ2xl",
"LlByb3RvYnVmLlJlZmxlY3Rpb24="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorSet), global::Google.Protobuf.Reflection.FileDescriptorSet.Parser, new[]{ "File" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorProto), global::Google.Protobuf.Reflection.FileDescriptorProto.Parser, new[]{ "Name", "Package", "Dependency", "PublicDependency", "WeakDependency", "MessageType", "EnumType", "Service", "Extension", "Options", "SourceCodeInfo", "Syntax" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorProto), global::Google.Protobuf.Reflection.FileDescriptorProto.Parser, new[]{ "Name", "Package", "Dependency", "PublicDependency", "WeakDependency", "MessageType", "EnumType", "Service", "Extension", "Options", "SourceCodeInfo", "Syntax", "Edition" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto), global::Google.Protobuf.Reflection.DescriptorProto.Parser, new[]{ "Name", "Field", "Extension", "NestedType", "EnumType", "ExtensionRange", "OneofDecl", "Options", "ReservedRange", "ReservedName" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange), global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange.Parser, new[]{ "Start", "End", "Options" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange), global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange.Parser, new[]{ "Start", "End" }, null, null, null, null)}),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ExtensionRangeOptions), global::Google.Protobuf.Reflection.ExtensionRangeOptions.Parser, new[]{ "UninterpretedOption" }, null, null, null, null),
@ -422,6 +422,7 @@ namespace Google.Protobuf.Reflection {
options_ = other.options_ != null ? other.options_.Clone() : null;
sourceCodeInfo_ = other.sourceCodeInfo_ != null ? other.sourceCodeInfo_.Clone() : null;
syntax_ = other.syntax_;
edition_ = other.edition_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
@ -616,7 +617,9 @@ namespace Google.Protobuf.Reflection {
private string syntax_;
/// <summary>
/// The syntax of the proto file.
/// The supported values are "proto2" and "proto3".
/// The supported values are "proto2", "proto3", and "editions".
///
/// If `edition` is present, this value must be "editions".
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
@ -639,6 +642,35 @@ namespace Google.Protobuf.Reflection {
syntax_ = null;
}
/// <summary>Field number for the "edition" field.</summary>
public const int EditionFieldNumber = 13;
private readonly static string EditionDefaultValue = "";
private string edition_;
/// <summary>
/// The edition of the proto file, which is an opaque string.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public string Edition {
get { return edition_ ?? EditionDefaultValue; }
set {
edition_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Gets whether the "edition" field is set</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public bool HasEdition {
get { return edition_ != null; }
}
/// <summary>Clears the value of the "edition" field</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void ClearEdition() {
edition_ = null;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public override bool Equals(object other) {
@ -666,6 +698,7 @@ namespace Google.Protobuf.Reflection {
if (!object.Equals(Options, other.Options)) return false;
if (!object.Equals(SourceCodeInfo, other.SourceCodeInfo)) return false;
if (Syntax != other.Syntax) return false;
if (Edition != other.Edition) return false;
return Equals(_unknownFields, other._unknownFields);
}
@ -685,6 +718,7 @@ namespace Google.Protobuf.Reflection {
if (options_ != null) hash ^= Options.GetHashCode();
if (sourceCodeInfo_ != null) hash ^= SourceCodeInfo.GetHashCode();
if (HasSyntax) hash ^= Syntax.GetHashCode();
if (HasEdition) hash ^= Edition.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
@ -730,6 +764,10 @@ namespace Google.Protobuf.Reflection {
output.WriteRawTag(98);
output.WriteString(Syntax);
}
if (HasEdition) {
output.WriteRawTag(106);
output.WriteString(Edition);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
@ -767,6 +805,10 @@ namespace Google.Protobuf.Reflection {
output.WriteRawTag(98);
output.WriteString(Syntax);
}
if (HasEdition) {
output.WriteRawTag(106);
output.WriteString(Edition);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
@ -799,6 +841,9 @@ namespace Google.Protobuf.Reflection {
if (HasSyntax) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Syntax);
}
if (HasEdition) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Edition);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
@ -839,6 +884,9 @@ namespace Google.Protobuf.Reflection {
if (other.HasSyntax) {
Syntax = other.Syntax;
}
if (other.HasEdition) {
Edition = other.Edition;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
@ -910,6 +958,10 @@ namespace Google.Protobuf.Reflection {
Syntax = input.ReadString();
break;
}
case 106: {
Edition = input.ReadString();
break;
}
}
}
#endif
@ -981,6 +1033,10 @@ namespace Google.Protobuf.Reflection {
Syntax = input.ReadString();
break;
}
case 106: {
Edition = input.ReadString();
break;
}
}
}
}

@ -33,6 +33,7 @@ pkg_files(
"bom/pom.xml",
"lite.md",
"pom.xml",
"protoc/pom.xml",
],
strip_prefix = strip_prefix.from_root(""),
visibility = ["//pkg:__pkg__"],

@ -8,7 +8,7 @@
</parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protoc</artifactId>
<version>3.21.2-rc1</version>
<version>3.21.2</version>
<packaging>pom</packaging>
<name>Protobuf Compiler</name>
<description>

@ -12,7 +12,8 @@
<name>Protocol Buffers [Util]</name>
<description>Utilities for Protocol Buffers</description>
{dependencies}
<dependencies>
{dependencies}
</dependencies>
</project>

@ -343,7 +343,8 @@ public final class Timestamps {
public static Timestamp fromDate(Date date) {
if (date instanceof java.sql.Timestamp) {
java.sql.Timestamp sqlTimestamp = (java.sql.Timestamp) date;
long integralSeconds = sqlTimestamp.getTime() / 1000L; // truncate the fractional seconds
long time = sqlTimestamp.getTime();
long integralSeconds = (time < 0) ? time / 1000L - 1 : time / 1000L ; // truncate the fractional seconds
return Timestamp.newBuilder()
.setSeconds(integralSeconds)
.setNanos(sqlTimestamp.getNanos())

@ -475,6 +475,13 @@ public class TimestampsTest {
Timestamp timestamp = Timestamps.fromDate(date);
assertThat(Timestamps.toString(timestamp)).isEqualTo("1970-01-01T00:00:01.111Z");
}
@Test
public void testFromSqlTimestamp_beforeEpoch() {
Date date = new java.sql.Timestamp(-1111);
Timestamp timestamp = Timestamps.fromDate(date);
assertThat(Timestamps.toString(timestamp)).isEqualTo("1969-12-31T23:59:58.889Z");
}
@Test
public void testTimeOperations() throws Exception {

@ -47,8 +47,10 @@ RUN cd /var/local \
&& make install
# Install composer
RUN curl -sS https://getcomposer.org/installer | php
RUN mv composer.phar /usr/local/bin/composer
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
RUN php composer-setup.php
RUN mv composer.phar /usr/bin/composer
RUN php -r "unlink('composer-setup.php');"
# Download php source code
RUN git clone https://github.com/php/php-src

@ -31,6 +31,7 @@ class Descriptor
->optional('options', \Google\Protobuf\Internal\GPBType::MESSAGE, 8, 'google.protobuf.internal.FileOptions')
->optional('source_code_info', \Google\Protobuf\Internal\GPBType::MESSAGE, 9, 'google.protobuf.internal.SourceCodeInfo')
->optional('syntax', \Google\Protobuf\Internal\GPBType::STRING, 12)
->optional('edition', \Google\Protobuf\Internal\GPBType::STRING, 13)
->finalizeToPool();
$pool->addMessage('google.protobuf.internal.DescriptorProto', \Google\Protobuf\Internal\DescriptorProto::class)

@ -81,11 +81,18 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message
protected $source_code_info = null;
/**
* The syntax of the proto file.
* The supported values are "proto2" and "proto3".
* The supported values are "proto2", "proto3", and "editions".
* If `edition` is present, this value must be "editions".
*
* Generated from protobuf field <code>optional string syntax = 12;</code>
*/
protected $syntax = null;
/**
* The edition of the proto file, which is an opaque string.
*
* Generated from protobuf field <code>optional string edition = 13;</code>
*/
protected $edition = null;
/**
* Constructor.
@ -117,7 +124,10 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message
* development tools.
* @type string $syntax
* The syntax of the proto file.
* The supported values are "proto2" and "proto3".
* The supported values are "proto2", "proto3", and "editions".
* If `edition` is present, this value must be "editions".
* @type string $edition
* The edition of the proto file, which is an opaque string.
* }
*/
public function __construct($data = NULL) {
@ -445,7 +455,8 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message
/**
* The syntax of the proto file.
* The supported values are "proto2" and "proto3".
* The supported values are "proto2", "proto3", and "editions".
* If `edition` is present, this value must be "editions".
*
* Generated from protobuf field <code>optional string syntax = 12;</code>
* @return string
@ -467,7 +478,8 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message
/**
* The syntax of the proto file.
* The supported values are "proto2" and "proto3".
* The supported values are "proto2", "proto3", and "editions".
* If `edition` is present, this value must be "editions".
*
* Generated from protobuf field <code>optional string syntax = 12;</code>
* @param string $var
@ -481,5 +493,41 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message
return $this;
}
/**
* The edition of the proto file, which is an opaque string.
*
* Generated from protobuf field <code>optional string edition = 13;</code>
* @return string
*/
public function getEdition()
{
return isset($this->edition) ? $this->edition : '';
}
public function hasEdition()
{
return isset($this->edition);
}
public function clearEdition()
{
unset($this->edition);
}
/**
* The edition of the proto file, which is an opaque string.
*
* Generated from protobuf field <code>optional string edition = 13;</code>
* @param string $var
* @return $this
*/
public function setEdition($var)
{
GPBUtil::checkString($var, True);
$this->edition = $var;
return $this;
}
}

@ -106,8 +106,8 @@ def protobuf_deps():
if not native.existing_rule("io_bazel_rules_kotlin"):
http_archive(
name = "io_bazel_rules_kotlin",
urls = ["https://github.com/bazelbuild/rules_kotlin/releases/download/v1.5.0-beta-4/rules_kotlin_release.tgz"],
sha256 = "6cbd4e5768bdfae1598662e40272729ec9ece8b7bded8f0d2c81c8ff96dc139d",
urls = ["https://github.com/bazelbuild/rules_kotlin/releases/download/v1.7.0-RC-1/rules_kotlin_release.tgz"],
sha256 = "68b910730026921814d3a504ccbe9adaac9938983d940e626523e6e4ecfb0355",
)
if not native.existing_rule("upb"):

@ -0,0 +1,55 @@
FROM centos:6.9
RUN yum install -y git \
tar \
wget \
make \
autoconf \
curl-devel \
unzip \
automake \
libtool \
glibc-static.i686 \
glibc-devel \
glibc-devel.i686 \
&& \
yum clean all
# Install Java 8
RUN wget -q --no-cookies --no-check-certificate \
--header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" \
"http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jdk-8u131-linux-x64.tar.gz" \
-O - | tar xz -C /var/local
ENV JAVA_HOME /var/local/jdk1.8.0_131
ENV PATH $JAVA_HOME/bin:$PATH
# Install Maven
RUN wget -q http://apache.cs.utah.edu/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz -O - | \
tar xz -C /var/local
ENV PATH /var/local/apache-maven-3.3.9/bin:$PATH
# Install GCC 4.8 to support -static-libstdc++
RUN wget http://people.centos.org/tru/devtools-2/devtools-2.repo -P /etc/yum.repos.d && \
bash -c 'echo "enabled=1" >> /etc/yum.repos.d/devtools-2.repo' && \
bash -c "sed -e 's/\$basearch/i386/g' /etc/yum.repos.d/devtools-2.repo > /etc/yum.repos.d/devtools-i386-2.repo" && \
sed -e 's/testing-/testing-i386-/g' -i /etc/yum.repos.d/devtools-i386-2.repo && \
rpm --rebuilddb
RUN yum install -y devtoolset-2-gcc \
devtoolset-2-gcc-c++ \
devtoolset-2-binutils \
devtoolset-2-libstdc++-devel \
devtoolset-2-libatomic-devel \
libatomic \
devtoolset-2-gcc.i686 \
devtoolset-2-gcc-c++.i686 \
devtoolset-2-binutils.i686 \
devtoolset-2-libstdc++-devel.i686 \
devtoolset-2-libatomic-devel.i686 \
libatomic.i686 && \
yum clean all
COPY scl-enable-devtoolset.sh /var/local/
# Start in devtoolset environment that uses GCC 4.7
ENTRYPOINT ["/var/local/scl-enable-devtoolset.sh"]

@ -2,13 +2,20 @@
``protoc`` is the compiler for ``.proto`` files. It generates language bindings
for the messages and/or RPC services from ``.proto`` files.
Because ``protoc`` is a native executable, we build and publish a ``protoc``
executable (a.k.a. artifact) to Maven repositories. The artifact can be used by
build automation tools so that users would not need to compile and install
``protoc`` for their systems.
Because ``protoc`` is a native executable, the scripts under this directory
build and publish a ``protoc`` executable (a.k.a. artifact) to Maven
repositories. The artifact can be used by build automation tools so that users
would not need to compile and install ``protoc`` for their systems.
The [pom.xml](pom.xml) file specifies configuration details used by Maven to
publish the protoc binaries. This is only used internally for releases.
If you would like us to publish protoc artifact for a new platform, please send
us a pull request to add support for the new platform. You would need to change
the following files:
* [build-protoc.sh](build-protoc.sh): script to cross-build the protoc for your
platform.
* [pom.xml](pom.xml): script to upload artifacts to maven.
* [build-zip.sh](build-zip.sh): script to package published maven artifacts in
our release page.
## Maven Location
The published protoc artifacts are available on Maven here:
@ -25,3 +32,130 @@ The name of a published ``protoc`` artifact is in the following format:
Note that artifacts for linux/macos also have the `.exe` suffix but they are
not windows binaries.
## System requirement
Install [Apache Maven](http://maven.apache.org/) if you don't have it.
The scripts only work under Unix-like environments, e.g., Linux, MacOSX, and
Cygwin or MinGW for Windows. Please see ``README.md`` of the Protobuf project
for how to set up the build environment.
## Building from a freshly checked-out source
If you just checked out the Protobuf source from github, you need to
generate the configure script.
Under the protobuf project directory:
```
$ ./autogen.sh
```
### Build the artifact for each platform
Run the build-protoc.sh script under this protoc-artifacts directory to build the protoc
artifact for each platform. For example:
```
$ cd protoc-artifacts
$ ./build-protoc.sh linux x86_64 protoc
```
The above command will produce a `target/linux/x86_64/protoc` binary under the
protoc-artifacts directory.
For a list of supported platforms, see the comments in the build-protoc.sh
script. We only use this script to build artifacts on Ubuntu and MacOS (both
with x86_64, and do cross-compilation for other platforms.
### Tips for building for Linux
We build on Centos 6.9 to provide a good compatibility for not very new
systems. We have provided a ``Dockerfile`` under this directory to build the
environment. It has been tested with Docker 1.6.1.
To build a image:
```
$ docker build -t protoc-artifacts .
```
To run the image:
```
$ docker run -it --rm=true protoc-artifacts bash
```
To checkout protobuf (run within the container):
```
$ # Replace v3.5.1 with the version you want
$ wget -O - https://github.com/protocolbuffers/protobuf/archive/v3.5.1.tar.gz | tar xvzp
```
### Windows build
We no longer use scripts in this directory to build windows artifacts. Instead,
we use Visual Studio 2015 to build our windows release artifacts. See our
[kokoro windows build scripts here](../kokoro/release/protoc/windows/build.bat).
To upload windows artifacts, copy the built binaries into this directory and
put it into the target/windows/(x86_64|x86_32) directory the same way as the
artifacts for other platforms. That will allow the maven script to find and
upload the artifacts to maven.
## To push artifacts to Maven Central
Before you can upload artifacts to Maven Central repository, make sure you have
read [this page](http://central.sonatype.org/pages/apache-maven.html) on how to
configure GPG and Sonatype account.
Before you do the deployment, make sure you have built the protoc artifacts for
every supported platform and put them under the target directory. Example
target directory layout:
+ pom.xml
+ target
+ linux
+ x86_64
protoc.exe
+ x86_32
protoc.exe
+ aarch_64
protoc.exe
+ ppcle_64
protoc.exe
+ s390_64
protoc.exe
+ osx
+ x86_64
protoc.exe
+ x86_32
protoc.exe
+ windows
+ x86_64
protoc.exe
+ x86_32
protoc.exe
You will need to build the artifacts on multiple machines and gather them
together into one place.
Use the following command to deploy artifacts for the host platform to a
staging repository.
```
$ mvn deploy -P release
```
It creates a new staging repository. Go to
https://oss.sonatype.org/#stagingRepositories and find the repository, usually
in the name like ``comgoogle-123``. Verify that the staging repository has all
the binaries, close and release this repository.
## Tested build environments
We have successfully built artifacts on the following environments:
- Linux x86_32 and x86_64:
- Centos 6.9 (within Docker 1.6.1)
- Ubuntu 14.04.5 64-bit
- Linux aarch_64: Cross compiled with `g++-aarch64-linux-gnu` on Ubuntu 14.04.5 64-bit
- Mac OS X x86_32 and x86_64: Mac OS X 10.9.5

@ -0,0 +1,294 @@
#!/bin/bash
# Builds protoc executable into target/<OS>/<ARCH>/protoc.exe; optionally builds
# protoc plugins into target/<OS>/<ARCH>/protoc-gen-*.exe
#
# Usage: ./build-protoc.sh <OS> <ARCH> <TARGET>
#
# <TARGET> can be "protoc" or "protoc-gen-javalite". Supported <OS> <ARCH>
# combinations:
# HOST <OS> <ARCH> <COMMENT>
# cygwin windows x86_32 Requires: i686-w64-mingw32-gcc
# cygwin windows x86_64 Requires: x86_64-w64-mingw32-gcc
# linux linux aarch_64 Requires: g++-aarch64-linux-gnu
# linux linux x86_32
# linux linux x86_64
# linux windows x86_32 Requires: i686-w64-mingw32-gcc
# linux windows x86_64 Requires: x86_64-w64-mingw32-gcc
# macos osx x86_32
# macos osx x86_64
# mingw windows x86_32
# mingw windows x86_64
#
# Before running this script, make sure you have generated the configure script
# in the parent directory (i.e., run ./autogen.sh there).
OS=$1
ARCH=$2
MAKE_TARGET=$3
if [[ $# < 3 ]]; then
echo "Not enough arguments provided."
exit 1
fi
case $MAKE_TARGET in
protoc-gen-javalite)
;;
protoc)
;;
*)
echo "Target ""$MAKE_TARGET"" invalid."
exit 1
esac
# Under Cygwin, bash doesn't have these in PATH when called from Maven which
# runs in Windows version of Java.
export PATH="/bin:/usr/bin:$PATH"
############################################################################
# Helper functions
############################################################################
E_PARAM_ERR=98
E_ASSERT_FAILED=99
# Usage:
fail()
{
echo "ERROR: $1"
echo
exit $E_ASSERT_FAILED
}
# Usage: assertEq VAL1 VAL2 $LINENO
assertEq ()
{
lineno=$3
if [ -z "$lineno" ]; then
echo "lineno not given"
exit $E_PARAM_ERR
fi
if [[ "$1" != "$2" ]]; then
echo "Assertion failed: \"$1\" == \"$2\""
echo "File \"$0\", line $lineno" # Give name of file and line number.
exit $E_ASSERT_FAILED
fi
}
# Checks the artifact is for the expected architecture
# Usage: checkArch <path-to-protoc>
checkArch ()
{
echo
echo "Checking file format ..."
if [[ "$OS" == windows || "$OS" == linux ]]; then
format="$(objdump -f "$1" | grep -o "file format .*$" | grep -o "[^ ]*$")"
echo Format=$format
if [[ "$OS" == linux ]]; then
host_machine="$(uname -m)";
if [[ "$ARCH" == x86_32 ]]; then
assertEq $format "elf32-i386" $LINENO
elif [[ "$ARCH" == x86_64 ]]; then
assertEq $format "elf64-x86-64" $LINENO
elif [[ "$ARCH" == aarch_64 ]]; then
assertEq $format "elf64-little" $LINENO
elif [[ "$ARCH" == s390_64 ]]; then
if [[ $host_machine == s390x ]];then
assertEq $format "elf64-s390" $LINENO
else
assertEq $format "elf64-big" $LINENO
fi
elif [[ "$ARCH" == ppcle_64 ]]; then
if [[ $host_machine == ppc64le ]];then
assertEq $format "elf64-powerpcle" $LINENO
else
assertEq $format "elf64-little" $LINENO
fi
else
fail "Unsupported arch: $ARCH"
fi
else
# $OS == windows
if [[ "$ARCH" == x86_32 ]]; then
assertEq $format "pei-i386" $LINENO
elif [[ "$ARCH" == x86_64 ]]; then
assertEq $format "pei-x86-64" $LINENO
else
fail "Unsupported arch: $ARCH"
fi
fi
elif [[ "$OS" == osx ]]; then
format="$(file -b "$1" | grep -o "[^ ]*$")"
echo Format=$format
if [[ "$ARCH" == x86_32 ]]; then
assertEq $format "i386" $LINENO
elif [[ "$ARCH" == x86_64 ]]; then
assertEq $format "x86_64" $LINENO
else
fail "Unsupported arch: $ARCH"
fi
else
fail "Unsupported system: $OS"
fi
echo
}
# Checks the dependencies of the artifact. Artifacts should only depend on
# system libraries.
# Usage: checkDependencies <path-to-protoc>
checkDependencies ()
{
if [[ "$OS" == windows ]]; then
dump_cmd='objdump -x '"$1"' | fgrep "DLL Name"'
white_list="KERNEL32\.dll\|msvcrt\.dll"
elif [[ "$OS" == linux ]]; then
host_machine="$(uname -m)";
dump_cmd='ldd '"$1"
if [[ "$ARCH" == x86_32 ]]; then
white_list="linux-gate\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux\.so\.2"
elif [[ "$ARCH" == x86_64 ]]; then
white_list="linux-vdso\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux-x86-64\.so\.2"
elif [[ "$ARCH" == s390_64 ]]; then
if [[ $host_machine != s390x ]];then
dump_cmd='objdump -p '"$1"' | grep NEEDED'
fi
white_list="linux-vdso64\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|libz\.so\.1\|ld64\.so\.1"
elif [[ "$ARCH" == ppcle_64 ]]; then
if [[ $host_machine != ppc64le ]];then
dump_cmd='objdump -p '"$1"' | grep NEEDED'
fi
white_list="linux-vdso64\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|libz\.so\.1\|ld64\.so\.2"
elif [[ "$ARCH" == aarch_64 ]]; then
dump_cmd='objdump -p '"$1"' | grep NEEDED'
white_list="libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux-aarch64\.so\.1"
fi
elif [[ "$OS" == osx ]]; then
dump_cmd='otool -L '"$1"' | fgrep dylib'
white_list="libz\.1\.dylib\|libstdc++\.6\.dylib\|libSystem\.B\.dylib"
fi
if [[ -z "$white_list" || -z "$dump_cmd" ]]; then
fail "Unsupported platform $OS-$ARCH."
fi
echo "Checking for expected dependencies ..."
eval $dump_cmd | grep -i "$white_list" || fail "doesn't show any expected dependencies"
echo "Checking for unexpected dependencies ..."
eval $dump_cmd | grep -i -v "$white_list"
ret=$?
if [[ $ret == 0 ]]; then
fail "found unexpected dependencies (listed above)."
elif [[ $ret != 1 ]]; then
fail "Error when checking dependencies."
fi # grep returns 1 when "not found", which is what we expect
echo "Dependencies look good."
echo
}
############################################################################
echo "Building protoc, OS=$OS ARCH=$ARCH TARGET=$MAKE_TARGET"
CONFIGURE_ARGS="--disable-shared"
if [[ "$OS" == windows ]]; then
MAKE_TARGET="${MAKE_TARGET}.exe"
fi
# Override the default value set in configure.ac that has '-g' which produces
# huge binary.
CXXFLAGS="-DNDEBUG"
LDFLAGS=""
if [[ "$(uname)" == CYGWIN* ]]; then
assertEq "$OS" windows $LINENO
# Use mingw32 compilers because executables produced by Cygwin compiler
# always have dependency on Cygwin DLL.
if [[ "$ARCH" == x86_64 ]]; then
CONFIGURE_ARGS="$CONFIGURE_ARGS --host=x86_64-w64-mingw32"
elif [[ "$ARCH" == x86_32 ]]; then
CONFIGURE_ARGS="$CONFIGURE_ARGS --host=i686-pc-mingw32"
else
fail "Unsupported arch by CYGWIN: $ARCH"
fi
elif [[ "$(uname)" == MINGW32* ]]; then
assertEq "$OS" windows $LINENO
assertEq "$ARCH" x86_32 $LINENO
elif [[ "$(uname)" == MINGW64* ]]; then
assertEq "$OS" windows $LINENO
assertEq "$ARCH" x86_64 $LINENO
elif [[ "$(uname)" == Linux* ]]; then
if [[ "$OS" == linux ]]; then
if [[ "$ARCH" == x86_64 ]]; then
CXXFLAGS="$CXXFLAGS -m64"
elif [[ "$ARCH" == x86_32 ]]; then
CXXFLAGS="$CXXFLAGS -m32"
elif [[ "$ARCH" == aarch_64 ]]; then
CONFIGURE_ARGS="$CONFIGURE_ARGS --host=aarch64-linux-gnu"
elif [[ "$ARCH" == ppcle_64 ]]; then
CXXFLAGS="$CXXFLAGS -m64"
CONFIGURE_ARGS="$CONFIGURE_ARGS --host=powerpc64le-linux-gnu"
elif [[ "$ARCH" == s390_64 ]]; then
CXXFLAGS="$CXXFLAGS -m64"
CONFIGURE_ARGS="$CONFIGURE_ARGS --host=s390x-linux-gnu"
else
fail "Unsupported arch: $ARCH"
fi
elif [[ "$OS" == windows ]]; then
# Cross-compilation for Windows
CONFIGURE_ARGS="$CONFIGURE_ARGS"
if [[ "$ARCH" == x86_64 ]]; then
CONFIGURE_ARGS="$CONFIGURE_ARGS --host=x86_64-w64-mingw32"
elif [[ "$ARCH" == x86_32 ]]; then
CONFIGURE_ARGS="$CONFIGURE_ARGS --host=i686-w64-mingw32"
else
fail "Unsupported arch: $ARCH"
fi
else
fail "Cannot build $OS on $(uname)"
fi
elif [[ "$(uname)" == Darwin* ]]; then
assertEq "$OS" osx $LINENO
# Make the binary compatible with OSX 10.7 and later
CXXFLAGS="$CXXFLAGS -mmacosx-version-min=10.7"
if [[ "$ARCH" == x86_64 ]]; then
CXXFLAGS="$CXXFLAGS -m64"
elif [[ "$ARCH" == x86_32 ]]; then
CXXFLAGS="$CXXFLAGS -m32"
else
fail "Unsupported arch: $ARCH"
fi
else
fail "Unsupported system: $(uname)"
fi
# Statically link libgcc and libstdc++.
# -s to produce stripped binary.
if [[ "$OS" == windows ]]; then
# Also static link libpthread required by mingw64
LDFLAGS="$LDFLAGS -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread -s"
elif [[ "$OS" != osx ]]; then
# And they don't work under Mac.
LDFLAGS="$LDFLAGS -static-libgcc -static-libstdc++ -s"
fi
export CXXFLAGS LDFLAGS
# Nested double quotes are unintuitive, but it works.
cd "$(dirname "$0")"
WORKING_DIR="$(pwd)"
BUILD_DIR="build/$OS/$ARCH"
TARGET_FILE="target/$OS/$ARCH/$MAKE_TARGET.exe"
mkdir -p "$BUILD_DIR" && cd "$BUILD_DIR" &&
../../../../configure $CONFIGURE_ARGS &&
cd src && make $MAKE_TARGET -j8 &&
cd "$WORKING_DIR" && mkdir -p $(dirname $TARGET_FILE) &&
cp $BUILD_DIR/src/$MAKE_TARGET $TARGET_FILE ||
exit 1
if [[ "$OS" == osx ]]; then
# Since Mac linker doesn't accept "-s", we need to run strip
strip $TARGET_FILE || exit 1
fi
checkArch $TARGET_FILE && checkDependencies $TARGET_FILE

@ -0,0 +1,120 @@
#!/bin/bash
if [ $# -ne 2 ]; then
cat <<EOF
Usage: $0 <TARGET> <VERSION_NUMBER>
TARGET: protoc | protoc-gen-javalite
Example:
$ $0 protoc 3.0.0
$ $0 protoc-gen-javalite 3.0.0
This script will download pre-built protoc or protoc plugin binaries from maven
repository and create .zip packages suitable to be included in the github
release page. If the target is protoc, well-known type .proto files will also be
included. Each invocation will create 8 zip packages:
dist/<TARGET>-<VERSION_NUMBER>-win32.zip
dist/<TARGET>-<VERSION_NUMBER>-win64.zip
dist/<TARGET>-<VERSION_NUMBER>-osx-aarch_64.zip
dist/<TARGET>-<VERSION_NUMBER>-osx-x86_64.zip
dist/<TARGET>-<VERSION_NUMBER>-linux-x86_32.zip
dist/<TARGET>-<VERSION_NUMBER>-linux-x86_64.zip
dist/<TARGET>-<VERSION_NUMBER>-linux-aarch_64.zip
dist/<TARGET>-<VERSION_NUMBER>-linux-ppcle_64.zip
dist/<TARGET>-<VERSION_NUMBER>-linux-s390_64.zip
EOF
exit 1
fi
TARGET=$1
VERSION_NUMBER=$2
# <zip file name> <binary file name> pairs.
declare -a FILE_NAMES=( \
win32.zip windows-x86_32.exe \
win64.zip windows-x86_64.exe \
osx-aarch_64.zip osx-aarch_64.exe \
osx-x86_64.zip osx-x86_64.exe \
linux-x86_32.zip linux-x86_32.exe \
linux-x86_64.zip linux-x86_64.exe \
linux-aarch_64.zip linux-aarch_64.exe \
linux-ppcle_64.zip linux-ppcle_64.exe \
linux-s390_64.zip linux-s390_64.exe \
)
# List of all well-known types to be included.
declare -a WELL_KNOWN_TYPES=( \
google/protobuf/descriptor.proto \
google/protobuf/any.proto \
google/protobuf/api.proto \
google/protobuf/duration.proto \
google/protobuf/empty.proto \
google/protobuf/field_mask.proto \
google/protobuf/source_context.proto \
google/protobuf/struct.proto \
google/protobuf/timestamp.proto \
google/protobuf/type.proto \
google/protobuf/wrappers.proto \
google/protobuf/compiler/plugin.proto \
)
set -e
# A temporary working directory to put all files.
DIR=$(mktemp -d)
# Copy over well-known types.
mkdir -p ${DIR}/include/google/protobuf/compiler
for PROTO in ${WELL_KNOWN_TYPES[@]}; do
cp -f ../src/${PROTO} ${DIR}/include/${PROTO}
done
# Create a readme file.
cat <<EOF > ${DIR}/readme.txt
Protocol Buffers - Google's data interchange format
Copyright 2008 Google Inc.
https://developers.google.com/protocol-buffers/
This package contains a precompiled binary version of the protocol buffer
compiler (protoc). This binary is intended for users who want to use Protocol
Buffers in languages other than C++ but do not want to compile protoc
themselves. To install, simply place this binary somewhere in your PATH.
If you intend to use the included well known types then don't forget to
copy the contents of the 'include' directory somewhere as well, for example
into '/usr/local/include/'.
Please refer to our official github site for more installation instructions:
https://github.com/protocolbuffers/protobuf
EOF
mkdir -p dist
mkdir -p ${DIR}/bin
# Create a zip file for each binary.
for((i=0;i<${#FILE_NAMES[@]};i+=2));do
ZIP_NAME=${FILE_NAMES[$i]}
if [ ${ZIP_NAME:0:3} = "win" ]; then
BINARY="$TARGET.exe"
else
BINARY="$TARGET"
fi
BINARY_NAME=${FILE_NAMES[$(($i+1))]}
BINARY_URL=https://repo1.maven.org/maven2/com/google/protobuf/$TARGET/${VERSION_NUMBER}/$TARGET-${VERSION_NUMBER}-${BINARY_NAME}
if ! wget ${BINARY_URL} -O ${DIR}/bin/$BINARY &> /dev/null; then
echo "[ERROR] Failed to download ${BINARY_URL}" >&2
echo "[ERROR] Skipped $TARGET-${VERSION_NAME}-${ZIP_NAME}" >&2
continue
fi
TARGET_ZIP_FILE=`pwd`/dist/$TARGET-${VERSION_NUMBER}-${ZIP_NAME}
pushd $DIR &> /dev/null
chmod +x bin/$BINARY
if [ "$TARGET" = "protoc" ]; then
zip -r ${TARGET_ZIP_FILE} include bin readme.txt &> /dev/null
else
zip -r ${TARGET_ZIP_FILE} bin &> /dev/null
fi
rm bin/$BINARY
popd &> /dev/null
echo "[INFO] Successfully created ${TARGET_ZIP_FILE}"
done

@ -603,6 +603,12 @@ class GeneratedDescriptorTest(unittest.TestCase):
def CheckDescriptorMapping(self, mapping):
# Verifies that a property like 'messageDescriptor.fields' has all the
# properties of an immutable abc.Mapping.
iterated_keys = []
for key in mapping:
iterated_keys.append(key)
self.assertEqual(len(iterated_keys), len(mapping))
self.assertEqual(set(iterated_keys), set(mapping.keys()))
self.assertNotEqual(
mapping, unittest_pb2.TestAllExtensions.DESCRIPTOR.fields_by_name)
self.assertNotEqual(mapping, {})
@ -619,10 +625,15 @@ class GeneratedDescriptorTest(unittest.TestCase):
with self.assertRaises(TypeError):
mapping.get()
# TODO(jieluo): Fix python and cpp extension diff.
if api_implementation.Type() == 'python':
self.assertRaises(TypeError, mapping.get, [])
else:
if api_implementation.Type() == 'cpp':
self.assertEqual(None, mapping.get([]))
else:
self.assertRaises(TypeError, mapping.get, [])
with self.assertRaises(TypeError):
if [] in mapping:
pass
with self.assertRaises(TypeError):
_ = mapping[[]]
# keys(), iterkeys() &co
item = (next(iter(mapping.keys())), next(iter(mapping.values())))
self.assertEqual(item, next(iter(mapping.items())))
@ -634,10 +645,12 @@ class GeneratedDescriptorTest(unittest.TestCase):
self.assertRaises(KeyError, mapping.__getitem__, 'key_error')
self.assertRaises(KeyError, mapping.__getitem__, len(mapping) + 1)
# TODO(jieluo): Add __repr__ support for DescriptorMapping.
if api_implementation.Type() == 'python':
self.assertEqual(len(str(dict(mapping.items()))), len(str(mapping)))
else:
if api_implementation.Type() == 'cpp':
self.assertEqual(str(mapping)[0], '<')
else:
print(str(dict(mapping.items()))[:100])
print(str(mapping)[:100])
self.assertEqual(len(str(dict(mapping.items()))), len(str(mapping)))
def testDescriptor(self):
message_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR

@ -183,11 +183,11 @@ void SerialArena::AllocateNewBlock(size_t n, const AllocationPolicy* policy) {
ThreadSafeArenaStats::RecordAllocateStats(arena_stats_, /*used=*/used,
/*allocated=*/mem.size, wasted);
set_head(new (mem.ptr) Block{head(), mem.size});
ptr_.store(head()->Pointer(kBlockHeaderSize), std::memory_order_relaxed);
set_ptr(head()->Pointer(kBlockHeaderSize));
limit_ = head()->Pointer(head()->size());
#ifdef ADDRESS_SANITIZER
ASAN_POISON_MEMORY_REGION(ptr_, limit_ - ptr_);
ASAN_POISON_MEMORY_REGION(ptr(), limit_ - ptr());
#endif // ADDRESS_SANITIZER
}

@ -252,7 +252,7 @@ struct AllocationPolicy {
ArenaMetricsCollector* metrics_collector = nullptr;
bool IsDefault() const {
return start_block_size == kDefaultMaxBlockSize &&
return start_block_size == kDefaultStartBlockSize &&
max_block_size == kDefaultMaxBlockSize && block_alloc == nullptr &&
block_dealloc == nullptr && metrics_collector == nullptr;
}
@ -499,11 +499,11 @@ class PROTOBUF_EXPORT SerialArena {
void (*destructor)(void*)) {
n = AlignUpTo(n, align);
#ifdef ADDRESS_SANITIZER
ASAN_UNPOISON_MEMORY_REGION(ptr_, n);
ASAN_UNPOISON_MEMORY_REGION(ptr(), n);
#endif // ADDRESS_SANITIZER
void* ret = internal::AlignTo(ptr_, align);
ptr_ += n;
GOOGLE_DCHECK_GE(limit_, ptr_);
void* ret = internal::AlignTo(ptr(), align);
set_ptr(ptr() + n);
GOOGLE_DCHECK_GE(limit_, ptr());
AddCleanupFromExisting(ret, destructor);
return ret;
}
@ -517,7 +517,7 @@ class PROTOBUF_EXPORT SerialArena {
ASAN_UNPOISON_MEMORY_REGION(limit_ - n, n);
#endif // ADDRESS_SANITIZER
limit_ -= n;
GOOGLE_DCHECK_GE(limit_, ptr_);
GOOGLE_DCHECK_GE(limit_, ptr());
cleanup::CreateNode(tag, limit_, elem, destructor);
}

@ -37,6 +37,8 @@
#include <cstdint>
#include <limits>
#include <map>
#include <unordered_set>
#include <utility>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/stubs/strutil.h>
@ -65,13 +67,44 @@ bool ShouldGenerateArraySize(const EnumDescriptor* descriptor) {
// Returns the number of unique numeric enum values. This is less than
// descriptor->value_count() when there are aliased values.
int CountUniqueValues(const EnumDescriptor* descriptor) {
std::set<int> values;
std::unordered_set<int> values;
for (int i = 0; i < descriptor->value_count(); ++i) {
values.insert(descriptor->value(i)->number());
}
return values.size();
}
struct MinMaxEnumDescriptors {
const EnumValueDescriptor* min;
const EnumValueDescriptor* max;
};
MinMaxEnumDescriptors EnumLimits(const EnumDescriptor* descriptor) {
const EnumValueDescriptor* min_desc = descriptor->value(0);
const EnumValueDescriptor* max_desc = descriptor->value(0);
for (int i = 1; i < descriptor->value_count(); ++i) {
if (descriptor->value(i)->number() < min_desc->number()) {
min_desc = descriptor->value(i);
}
if (descriptor->value(i)->number() > max_desc->number()) {
max_desc = descriptor->value(i);
}
}
return {min_desc, max_desc};
}
// Assumes that HasDescriptorMethods is true.
bool ShouldCacheDenseEnum(const EnumDescriptor* descriptor,
MinMaxEnumDescriptors limits) {
// The conditions here for what is "sparse" are not rigorously
// chosen. We use unsigned values in case the subtraction of min from max
// exceeds the bounds of int.
const unsigned values_range = static_cast<unsigned>(limits.max->number()) -
static_cast<unsigned>(limits.min->number());
return (values_range < 16u ||
values_range < static_cast<unsigned>(descriptor->value_count()) * 2u);
}
} // namespace
EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
@ -98,9 +131,6 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
format("enum ${1$$classname$$}$ : int {\n", descriptor_);
format.Indent();
const EnumValueDescriptor* min_value = descriptor_->value(0);
const EnumValueDescriptor* max_value = descriptor_->value(0);
for (int i = 0; i < descriptor_->value_count(); i++) {
auto format_value = format;
format_value.Set("name", EnumValueName(descriptor_->value(i)));
@ -114,13 +144,6 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
if (i > 0) format_value(",\n");
format_value("${1$$prefix$$name$$}$ $deprecation$= $number$",
descriptor_->value(i));
if (descriptor_->value(i)->number() < min_value->number()) {
min_value = descriptor_->value(i);
}
if (descriptor_->value(i)->number() > max_value->number()) {
max_value = descriptor_->value(i);
}
}
if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
@ -137,13 +160,15 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
format.Outdent();
format("\n};\n");
MinMaxEnumDescriptors enum_limits = EnumLimits(descriptor_);
format(
"$dllexport_decl $bool $classname$_IsValid(int value);\n"
"constexpr $classname$ ${1$$prefix$$short_name$_MIN$}$ = "
"$prefix$$2$;\n"
"constexpr $classname$ ${1$$prefix$$short_name$_MAX$}$ = "
"$prefix$$3$;\n",
descriptor_, EnumValueName(min_value), EnumValueName(max_value));
descriptor_, EnumValueName(enum_limits.min),
EnumValueName(enum_limits.max));
if (generate_array_size_) {
format(
@ -172,9 +197,19 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
" ::std::is_integral<T>::value,\n"
" \"Incorrect type passed to function $classname$_Name.\");\n");
if (HasDescriptorMethods(descriptor_->file(), options_)) {
format(
" return ::$proto_ns$::internal::NameOfEnum(\n"
" $classname$_descriptor(), enum_t_value);\n");
if (ShouldCacheDenseEnum(descriptor_, enum_limits)) {
// Using the NameOfEnum routine can be slow, so we create a small
// cache of pointers to the std::string objects that reflection
// stores internally. This cache is a simple contiguous array of
// pointers, so if the enum values are sparse, it's not worth it.
format(
" return "
"$classname$_Name(static_cast<$classname$>(enum_t_value));\n");
} else {
format(
" return ::$proto_ns$::internal::NameOfEnum(\n"
" $classname$_descriptor(), enum_t_value);\n");
}
} else {
format(
" return $classname$_Name(static_cast<$classname$>(enum_t_value));\n");
@ -182,6 +217,11 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
format("}\n");
if (HasDescriptorMethods(descriptor_->file(), options_)) {
if (ShouldCacheDenseEnum(descriptor_, enum_limits)) {
format(
"template<> $dllexport_decl $"
"const std::string& $classname$_Name($classname$ value);\n");
}
format(
"inline bool $classname$_Parse(\n"
" ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, $classname$* "
@ -276,6 +316,18 @@ void EnumGenerator::GenerateMethods(int idx, io::Printer* printer) {
" return $file_level_enum_descriptors$[$1$];\n"
"}\n",
idx);
MinMaxEnumDescriptors enum_limits = EnumLimits(descriptor_);
if (ShouldCacheDenseEnum(descriptor_, enum_limits)) {
format(
"template<> $dllexport_decl $"
"const std::string& $classname$_Name(\n"
" $classname$ value) {\n"
" return ::$proto_ns$::internal::NameOfDenseEnum\n"
" <$classname$_descriptor, $1$, $2$>(static_cast<int>(value));\n"
"}\n",
enum_limits.min->number(), enum_limits.max->number());
}
}
format(

@ -34,6 +34,7 @@
#include <google/protobuf/compiler/cpp/helpers.h>
#include <algorithm>
#include <cstdint>
#include <functional>
#include <limits>
@ -872,6 +873,10 @@ std::string SafeFunctionName(const Descriptor* descriptor,
return function_name;
}
bool IsProfileDriven(const Options& options) {
return options.access_info_map != nullptr;
}
bool IsStringInlined(const FieldDescriptor* descriptor,
const Options& options) {

@ -327,6 +327,8 @@ inline bool IsWeak(const FieldDescriptor* field, const Options& options) {
return false;
}
bool IsProfileDriven(const Options& options);
bool IsStringInlined(const FieldDescriptor* descriptor, const Options& options);
// For a string field, returns the effective ctype. If the actual ctype is

@ -2722,19 +2722,6 @@ void MessageGenerator::GenerateCopyConstructorBody(io::Printer* printer) const {
" static_cast<size_t>(reinterpret_cast<char*>(&$last$) -\n"
" reinterpret_cast<char*>(&$first$)) + sizeof($last$));\n";
if (ShouldSplit(descriptor_, options_)) {
format("if (!from.IsSplitMessageDefault()) {\n");
format.Indent();
format("_this->PrepareSplitMessageForWrite();\n");
for (auto field : optimized_order_) {
if (ShouldSplit(field, options_)) {
field_generators_.get(field).GenerateCopyConstructorCode(printer);
}
}
format.Outdent();
format("}\n");
}
for (size_t i = 0; i < optimized_order_.size(); ++i) {
const FieldDescriptor* field = optimized_order_[i];
if (ShouldSplit(field, options_)) {
@ -2763,6 +2750,20 @@ void MessageGenerator::GenerateCopyConstructorBody(io::Printer* printer) const {
field_generators_.get(field).GenerateCopyConstructorCode(printer);
}
}
if (ShouldSplit(descriptor_, options_)) {
format("if (!from.IsSplitMessageDefault()) {\n");
format.Indent();
format("_this->PrepareSplitMessageForWrite();\n");
// TODO(b/122856539): cache the split pointers.
for (auto field : optimized_order_) {
if (ShouldSplit(field, options_)) {
field_generators_.get(field).GenerateCopyConstructorCode(printer);
}
}
format.Outdent();
format("}\n");
}
}
void MessageGenerator::GenerateStructors(io::Printer* printer) {
@ -3037,15 +3038,26 @@ void MessageGenerator::GenerateClear(io::Printer* printer) {
ColdChunkSkipper cold_skipper(descriptor_, options_, chunks, has_bit_indices_,
kColdRatio);
int cached_has_word_index = -1;
for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) {
bool first_split_chunk_processed = false;
for (size_t chunk_index = 0; chunk_index < chunks.size(); chunk_index++) {
std::vector<const FieldDescriptor*>& chunk = chunks[chunk_index];
cold_skipper.OnStartChunk(chunk_index, cached_has_word_index, "", printer);
const FieldDescriptor* memset_start = nullptr;
const FieldDescriptor* memset_end = nullptr;
bool saw_non_zero_init = false;
bool chunk_is_cold = !chunk.empty() && ShouldSplit(chunk.front(), options_);
bool chunk_is_split =
!chunk.empty() && ShouldSplit(chunk.front(), options_);
// All chunks after the first split chunk should also be split.
GOOGLE_CHECK(!first_split_chunk_processed || chunk_is_split);
if (chunk_is_split && !first_split_chunk_processed) {
// Some fields are cleared without checking has_bit. So we add the
// condidtion here to avoid writing to the default split instance.
format("if (!IsSplitMessageDefault()) {\n");
format.Indent();
first_split_chunk_processed = true;
}
for (const auto& field : chunk) {
if (CanInitializeByZeroing(field)) {
GOOGLE_CHECK(!saw_non_zero_init);
@ -3085,25 +3097,20 @@ void MessageGenerator::GenerateClear(io::Printer* printer) {
format.Indent();
}
if (chunk_is_cold) {
format("if (!IsSplitMessageDefault()) {\n");
format.Indent();
}
if (memset_start) {
if (memset_start == memset_end) {
// For clarity, do not memset a single field.
field_generators_.get(memset_start)
.GenerateMessageClearingCode(printer);
} else {
GOOGLE_CHECK_EQ(chunk_is_cold, ShouldSplit(memset_start, options_));
GOOGLE_CHECK_EQ(chunk_is_cold, ShouldSplit(memset_end, options_));
GOOGLE_CHECK_EQ(chunk_is_split, ShouldSplit(memset_start, options_));
GOOGLE_CHECK_EQ(chunk_is_split, ShouldSplit(memset_end, options_));
format(
"::memset(&$1$, 0, static_cast<size_t>(\n"
" reinterpret_cast<char*>(&$2$) -\n"
" reinterpret_cast<char*>(&$1$)) + sizeof($2$));\n",
FieldMemberName(memset_start, chunk_is_cold),
FieldMemberName(memset_end, chunk_is_cold));
FieldMemberName(memset_start, chunk_is_split),
FieldMemberName(memset_end, chunk_is_split));
}
}
@ -3132,14 +3139,16 @@ void MessageGenerator::GenerateClear(io::Printer* printer) {
}
}
if (chunk_is_cold) {
if (have_outer_if) {
format.Outdent();
format("}\n");
}
if (have_outer_if) {
format.Outdent();
format("}\n");
if (chunk_index == chunks.size() - 1) {
if (first_split_chunk_processed) {
format.Outdent();
format("}\n");
}
}
if (cold_skipper.OnEndChunk(chunk_index, printer)) {

@ -40,6 +40,7 @@ namespace google {
namespace protobuf {
namespace compiler {
class AccessInfoMap;
class SplitMap;
namespace cpp {
@ -58,6 +59,7 @@ struct FieldListenerOptions {
// Generator options (see generator.cc for a description of each):
struct Options {
const AccessInfoMap* access_info_map = nullptr;
const SplitMap* split_map = nullptr;
std::string dllexport_decl;
std::string runtime_include_base;
std::string annotation_pragma_name;
@ -83,6 +85,7 @@ struct Options {
bool profile_driven_inline_string = true;
bool message_owned_arena_trial = false;
bool force_split = false;
bool profile_driven_split = false;
#ifdef PROTOBUF_STABLE_EXPERIMENTS
bool force_eagerly_verified_lazy = true;
bool force_inline_string = true;

@ -85,41 +85,11 @@ class FieldGroup {
} // namespace
// Reorder 'fields' so that if the fields are output into a c++ class in the new
// order, fields of similar family (see below) are together and within each
// family, alignment padding is minimized.
//
// We try to do this while keeping each field as close as possible to its field
// number order so that we don't reduce cache locality much for function that
// access each field in order. Originally, OptimizePadding used declaration
// order for its decisions, but generated code minus the serializer/parsers uses
// the output of OptimizePadding as well (stored in
// MessageGenerator::optimized_order_). Since the serializers use field number
// order, we use that as a tie-breaker.
//
// We classify each field into a particular "family" of fields, that we perform
// the same operation on in our generated functions.
//
// REPEATED is placed first, as the C++ compiler automatically initializes
// these fields in layout order.
//
// STRING is grouped next, as our Clear/SharedCtor/SharedDtor walks it and
// calls ArenaStringPtr::Destroy on each.
//
// LAZY_MESSAGE is grouped next, as it interferes with the ability to memset
// non-repeated fields otherwise.
//
// MESSAGE is grouped next, as our Clear/SharedDtor code walks it and calls
// delete on each. We initialize these fields with a NULL pointer (see
// MessageFieldGenerator::GenerateConstructorCode), which allows them to be
// memset.
//
// ZERO_INITIALIZABLE is memset in Clear/SharedCtor
//
// OTHER these fields are initialized one-by-one.
void PaddingOptimizer::OptimizeLayout(
std::vector<const FieldDescriptor*>* fields, const Options& options,
MessageSCCAnalyzer* scc_analyzer) {
static void OptimizeLayoutHelper(std::vector<const FieldDescriptor*>* fields,
const Options& options,
MessageSCCAnalyzer* scc_analyzer) {
if (fields->empty()) return;
// The sorted numeric order of Family determines the declaration order in the
// memory layout.
enum Family {
@ -222,6 +192,61 @@ void PaddingOptimizer::OptimizeLayout(
}
}
// Reorder 'fields' so that if the fields are output into a c++ class in the new
// order, fields of similar family (see below) are together and within each
// family, alignment padding is minimized.
//
// We try to do this while keeping each field as close as possible to its field
// number order so that we don't reduce cache locality much for function that
// access each field in order. Originally, OptimizePadding used declaration
// order for its decisions, but generated code minus the serializer/parsers uses
// the output of OptimizePadding as well (stored in
// MessageGenerator::optimized_order_). Since the serializers use field number
// order, we use that as a tie-breaker.
//
// We classify each field into a particular "family" of fields, that we perform
// the same operation on in our generated functions.
//
// REPEATED is placed first, as the C++ compiler automatically initializes
// these fields in layout order.
//
// STRING is grouped next, as our Clear/SharedCtor/SharedDtor walks it and
// calls ArenaStringPtr::Destroy on each.
//
// LAZY_MESSAGE is grouped next, as it interferes with the ability to memset
// non-repeated fields otherwise.
//
// MESSAGE is grouped next, as our Clear/SharedDtor code walks it and calls
// delete on each. We initialize these fields with a NULL pointer (see
// MessageFieldGenerator::GenerateConstructorCode), which allows them to be
// memset.
//
// ZERO_INITIALIZABLE is memset in Clear/SharedCtor
//
// OTHER these fields are initialized one-by-one.
//
// If there are split fields in `fields`, they will be placed at the end. The
// order within split fields follows the same rule, aka classify and order by
// "family".
void PaddingOptimizer::OptimizeLayout(
std::vector<const FieldDescriptor*>* fields, const Options& options,
MessageSCCAnalyzer* scc_analyzer) {
std::vector<const FieldDescriptor*> normal;
std::vector<const FieldDescriptor*> split;
for (const auto* field : *fields) {
if (ShouldSplit(field, options)) {
split.push_back(field);
} else {
normal.push_back(field);
}
}
OptimizeLayoutHelper(&normal, options, scc_analyzer);
OptimizeLayoutHelper(&split, options, scc_analyzer);
fields->clear();
fields->insert(fields->end(), normal.begin(), normal.end());
fields->insert(fields->end(), split.begin(), split.end());
}
} // namespace cpp
} // namespace compiler
} // namespace protobuf

@ -37,6 +37,7 @@
#include <google/protobuf/wire_format.h>
#include <google/protobuf/compiler/cpp/helpers.h>
#include <google/protobuf/generated_message_tctable_impl.h>
namespace google {
namespace protobuf {
@ -289,21 +290,32 @@ TailCallTableInfo::TailCallTableInfo(
MessageSCCAnalyzer* scc_analyzer) {
// If this message has any inlined string fields, store the donation state
// offset in the second auxiliary entry.
const auto set_fixed_aux_entry = [&](int index, const std::string& value) {
if (index >= aux_entries.size()) {
aux_entries.resize(index + 1); // pad if necessary
}
aux_entries[index] = value;
};
if (!inlined_string_indices.empty()) {
aux_entries.resize(1); // pad if necessary
aux_entries[0] =
set_fixed_aux_entry(
internal::kInlinedStringAuxIdx,
StrCat("_fl::Offset{offsetof(", ClassName(descriptor),
", _impl_._inlined_string_donated_)}");
", _impl_._inlined_string_donated_)}"));
}
// If this message is split, store the split pointer offset in the third
// auxiliary entry.
if (ShouldSplit(descriptor, options)) {
aux_entries.resize(4); // pad if necessary
aux_entries[2] = StrCat("_fl::Offset{offsetof(",
ClassName(descriptor), ", _impl_._split_)}");
aux_entries[3] = StrCat("_fl::Offset{sizeof(", ClassName(descriptor),
"::Impl_::Split)}");
set_fixed_aux_entry(
internal::kSplitOffsetAuxIdx,
StrCat("_fl::Offset{offsetof(", ClassName(descriptor),
", _impl_._split_)}"));
set_fixed_aux_entry(
internal::kSplitSizeAuxIdx,
StrCat("_fl::Offset{sizeof(", ClassName(descriptor),
"::Impl_::Split)}"));
}
// Fill in mini table entries.

@ -147,7 +147,9 @@ static void WriteDocCommentBodyForLocation(io::Printer* printer,
? location.trailing_comments
: location.leading_comments;
if (!comments.empty()) {
if (!kdoc) {
if (kdoc) {
comments = EscapeKdoc(comments);
} else {
comments = EscapeJavadoc(comments);
}

@ -47,7 +47,7 @@ std::string SafelyPrintIntToCode(int v) {
if (v == std::numeric_limits<int>::min()) {
// Some compilers try to parse -2147483648 as two tokens and then get spicy
// about the fact that +2147483648 cannot be represented as an int.
return "-2147483647 - 1";
return StrCat(v + 1, " - 1");
} else {
return StrCat(v);
}

@ -219,6 +219,11 @@ const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* CodeGeneratorResponse_Feature_des
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto);
return file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto[0];
}
template<> PROTOC_EXPORT const std::string& CodeGeneratorResponse_Feature_Name(
CodeGeneratorResponse_Feature value) {
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum
<CodeGeneratorResponse_Feature_descriptor, 0, 1>(static_cast<int>(value));
}
bool CodeGeneratorResponse_Feature_IsValid(int value) {
switch (value) {
case 0:

@ -92,9 +92,9 @@ inline const std::string& CodeGeneratorResponse_Feature_Name(T enum_t_value) {
static_assert(::std::is_same<T, CodeGeneratorResponse_Feature>::value ||
::std::is_integral<T>::value,
"Incorrect type passed to function CodeGeneratorResponse_Feature_Name.");
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
CodeGeneratorResponse_Feature_descriptor(), enum_t_value);
return CodeGeneratorResponse_Feature_Name(static_cast<CodeGeneratorResponse_Feature>(enum_t_value));
}
template<> PROTOC_EXPORT const std::string& CodeGeneratorResponse_Feature_Name(CodeGeneratorResponse_Feature value);
inline bool CodeGeneratorResponse_Feature_Parse(
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, CodeGeneratorResponse_Feature* value) {
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<CodeGeneratorResponse_Feature>(

@ -483,7 +483,8 @@ PROTOBUF_CONSTEXPR GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(
, /*decltype(_impl_._path_cached_byte_size_)*/{0}
, /*decltype(_impl_.source_file_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
, /*decltype(_impl_.begin_)*/0
, /*decltype(_impl_.end_)*/0} {}
, /*decltype(_impl_.end_)*/0
, /*decltype(_impl_.semantic_)*/0} {}
struct GeneratedCodeInfo_AnnotationDefaultTypeInternal {
PROTOBUF_CONSTEXPR GeneratedCodeInfo_AnnotationDefaultTypeInternal()
: _instance(::_pbi::ConstantInitialized{}) {}
@ -508,7 +509,7 @@ struct GeneratedCodeInfoDefaultTypeInternal {
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 GeneratedCodeInfoDefaultTypeInternal _GeneratedCodeInfo_default_instance_;
PROTOBUF_NAMESPACE_CLOSE
static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[27];
static const ::_pb::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[6];
static const ::_pb::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[7];
static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fdescriptor_2eproto = nullptr;
const uint32_t TableStruct_google_2fprotobuf_2fdescriptor_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
@ -964,10 +965,12 @@ const uint32_t TableStruct_google_2fprotobuf_2fdescriptor_2eproto::offsets[] PRO
PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _impl_.source_file_),
PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _impl_.begin_),
PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _impl_.end_),
PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _impl_.semantic_),
~0u,
0,
1,
2,
3,
~0u, // no _has_bits_
PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo, _internal_metadata_),
~0u, // no _extensions_
@ -1004,8 +1007,8 @@ static const ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protode
{ 391, 406, -1, sizeof(::PROTOBUF_NAMESPACE_ID::UninterpretedOption)},
{ 413, 426, -1, sizeof(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location)},
{ 431, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo)},
{ 440, 452, -1, sizeof(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation)},
{ 456, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo)},
{ 440, 453, -1, sizeof(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation)},
{ 458, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo)},
};
static const ::_pb::Message* const file_default_instances[] = {
@ -1183,19 +1186,22 @@ const char descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto[] PR
"rceCodeInfo.Location\032\206\001\n\010Location\022\020\n\004pat"
"h\030\001 \003(\005B\002\020\001\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020leading"
"_comments\030\003 \001(\t\022\031\n\021trailing_comments\030\004 \001"
"(\t\022!\n\031leading_detached_comments\030\006 \003(\t\"\247\001"
"(\t\022!\n\031leading_detached_comments\030\006 \003(\t\"\234\002"
"\n\021GeneratedCodeInfo\022A\n\nannotation\030\001 \003(\0132"
"-.google.protobuf.GeneratedCodeInfo.Anno"
"tation\032O\n\nAnnotation\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023"
"\n\013source_file\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003en"
"d\030\004 \001(\005B~\n\023com.google.protobufB\020Descript"
"orProtosH\001Z-google.golang.org/protobuf/t"
"ypes/descriptorpb\370\001\001\242\002\003GPB\252\002\032Google.Prot"
"obuf.Reflection"
"tation\032\303\001\n\nAnnotation\022\020\n\004path\030\001 \003(\005B\002\020\001\022"
"\023\n\013source_file\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003e"
"nd\030\004 \001(\005\022H\n\010semantic\030\005 \001(\01626.google.prot"
"obuf.GeneratedCodeInfo.Annotation.Semant"
"ic\"(\n\010Semantic\022\010\n\004NONE\020\000\022\007\n\003SET\020\001\022\t\n\005ALI"
"AS\020\002B~\n\023com.google.protobufB\020DescriptorP"
"rotosH\001Z-google.golang.org/protobuf/type"
"s/descriptorpb\370\001\001\242\002\003GPB\252\002\032Google.Protobu"
"f.Reflection"
;
static ::_pbi::once_flag descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once;
const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fdescriptor_2eproto = {
false, false, 6095, descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto,
false, false, 6212, descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto,
"google/protobuf/descriptor.proto",
&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, nullptr, 0, 27,
schemas, file_default_instances, TableStruct_google_2fprotobuf_2fdescriptor_2eproto::offsets,
@ -1213,6 +1219,11 @@ const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldDescriptorProto_Type_descrip
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[0];
}
template<> PROTOBUF_EXPORT const std::string& FieldDescriptorProto_Type_Name(
FieldDescriptorProto_Type value) {
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum
<FieldDescriptorProto_Type_descriptor, 1, 18>(static_cast<int>(value));
}
bool FieldDescriptorProto_Type_IsValid(int value) {
switch (value) {
case 1:
@ -1266,6 +1277,11 @@ const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldDescriptorProto_Label_descri
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[1];
}
template<> PROTOBUF_EXPORT const std::string& FieldDescriptorProto_Label_Name(
FieldDescriptorProto_Label value) {
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum
<FieldDescriptorProto_Label_descriptor, 1, 3>(static_cast<int>(value));
}
bool FieldDescriptorProto_Label_IsValid(int value) {
switch (value) {
case 1:
@ -1289,6 +1305,11 @@ const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FileOptions_OptimizeMode_descript
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[2];
}
template<> PROTOBUF_EXPORT const std::string& FileOptions_OptimizeMode_Name(
FileOptions_OptimizeMode value) {
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum
<FileOptions_OptimizeMode_descriptor, 1, 3>(static_cast<int>(value));
}
bool FileOptions_OptimizeMode_IsValid(int value) {
switch (value) {
case 1:
@ -1312,6 +1333,11 @@ const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldOptions_CType_descriptor() {
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[3];
}
template<> PROTOBUF_EXPORT const std::string& FieldOptions_CType_Name(
FieldOptions_CType value) {
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum
<FieldOptions_CType_descriptor, 0, 2>(static_cast<int>(value));
}
bool FieldOptions_CType_IsValid(int value) {
switch (value) {
case 0:
@ -1335,6 +1361,11 @@ const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldOptions_JSType_descriptor()
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[4];
}
template<> PROTOBUF_EXPORT const std::string& FieldOptions_JSType_Name(
FieldOptions_JSType value) {
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum
<FieldOptions_JSType_descriptor, 0, 2>(static_cast<int>(value));
}
bool FieldOptions_JSType_IsValid(int value) {
switch (value) {
case 0:
@ -1358,6 +1389,11 @@ const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* MethodOptions_IdempotencyLevel_de
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[5];
}
template<> PROTOBUF_EXPORT const std::string& MethodOptions_IdempotencyLevel_Name(
MethodOptions_IdempotencyLevel value) {
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum
<MethodOptions_IdempotencyLevel_descriptor, 0, 2>(static_cast<int>(value));
}
bool MethodOptions_IdempotencyLevel_IsValid(int value) {
switch (value) {
case 0:
@ -1377,6 +1413,34 @@ 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 && _MSC_VER < 1912))
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* GeneratedCodeInfo_Annotation_Semantic_descriptor() {
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[6];
}
template<> PROTOBUF_EXPORT const std::string& GeneratedCodeInfo_Annotation_Semantic_Name(
GeneratedCodeInfo_Annotation_Semantic value) {
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum
<GeneratedCodeInfo_Annotation_Semantic_descriptor, 0, 2>(static_cast<int>(value));
}
bool GeneratedCodeInfo_Annotation_Semantic_IsValid(int value) {
switch (value) {
case 0:
case 1:
case 2:
return true;
default:
return false;
}
}
#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
constexpr GeneratedCodeInfo_Annotation_Semantic GeneratedCodeInfo_Annotation::NONE;
constexpr GeneratedCodeInfo_Annotation_Semantic GeneratedCodeInfo_Annotation::SET;
constexpr GeneratedCodeInfo_Annotation_Semantic GeneratedCodeInfo_Annotation::ALIAS;
constexpr GeneratedCodeInfo_Annotation_Semantic GeneratedCodeInfo_Annotation::Semantic_MIN;
constexpr GeneratedCodeInfo_Annotation_Semantic GeneratedCodeInfo_Annotation::Semantic_MAX;
constexpr int GeneratedCodeInfo_Annotation::Semantic_ARRAYSIZE;
#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
// ===================================================================
@ -10882,6 +10946,9 @@ class GeneratedCodeInfo_Annotation::_Internal {
static void set_has_end(HasBits* has_bits) {
(*has_bits)[0] |= 4u;
}
static void set_has_semantic(HasBits* has_bits) {
(*has_bits)[0] |= 8u;
}
};
GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(::PROTOBUF_NAMESPACE_ID::Arena* arena,
@ -10900,7 +10967,8 @@ GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(const GeneratedCodeIn
, /*decltype(_impl_._path_cached_byte_size_)*/{0}
, decltype(_impl_.source_file_){}
, decltype(_impl_.begin_){}
, decltype(_impl_.end_){}};
, decltype(_impl_.end_){}
, decltype(_impl_.semantic_){}};
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
_impl_.source_file_.InitDefault();
@ -10912,8 +10980,8 @@ GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(const GeneratedCodeIn
_this->GetArenaForAllocation());
}
::memcpy(&_impl_.begin_, &from._impl_.begin_,
static_cast<size_t>(reinterpret_cast<char*>(&_impl_.end_) -
reinterpret_cast<char*>(&_impl_.begin_)) + sizeof(_impl_.end_));
static_cast<size_t>(reinterpret_cast<char*>(&_impl_.semantic_) -
reinterpret_cast<char*>(&_impl_.begin_)) + sizeof(_impl_.semantic_));
// @@protoc_insertion_point(copy_constructor:google.protobuf.GeneratedCodeInfo.Annotation)
}
@ -10929,6 +10997,7 @@ inline void GeneratedCodeInfo_Annotation::SharedCtor(
, decltype(_impl_.source_file_){}
, decltype(_impl_.begin_){0}
, decltype(_impl_.end_){0}
, decltype(_impl_.semantic_){0}
};
_impl_.source_file_.InitDefault();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
@ -10966,10 +11035,10 @@ void GeneratedCodeInfo_Annotation::Clear() {
if (cached_has_bits & 0x00000001u) {
_impl_.source_file_.ClearNonDefaultToEmpty();
}
if (cached_has_bits & 0x00000006u) {
if (cached_has_bits & 0x0000000eu) {
::memset(&_impl_.begin_, 0, static_cast<size_t>(
reinterpret_cast<char*>(&_impl_.end_) -
reinterpret_cast<char*>(&_impl_.begin_)) + sizeof(_impl_.end_));
reinterpret_cast<char*>(&_impl_.semantic_) -
reinterpret_cast<char*>(&_impl_.begin_)) + sizeof(_impl_.semantic_));
}
_impl_._has_bits_.Clear();
_internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
@ -11023,6 +11092,19 @@ const char* GeneratedCodeInfo_Annotation::_InternalParse(const char* ptr, ::_pbi
} else
goto handle_unusual;
continue;
// optional .google.protobuf.GeneratedCodeInfo.Annotation.Semantic semantic = 5;
case 5:
if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 40)) {
uint64_t val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
CHK_(ptr);
if (PROTOBUF_PREDICT_TRUE(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic_IsValid(val))) {
_internal_set_semantic(static_cast<::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic>(val));
} else {
::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(5, val, mutable_unknown_fields());
}
} else
goto handle_unusual;
continue;
default:
goto handle_unusual;
} // switch
@ -11085,6 +11167,13 @@ uint8_t* GeneratedCodeInfo_Annotation::_InternalSerialize(
target = ::_pbi::WireFormatLite::WriteInt32ToArray(4, this->_internal_end(), target);
}
// optional .google.protobuf.GeneratedCodeInfo.Annotation.Semantic semantic = 5;
if (cached_has_bits & 0x00000008u) {
target = stream->EnsureSpace(target);
target = ::_pbi::WireFormatLite::WriteEnumToArray(
5, this->_internal_semantic(), target);
}
if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
_internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
@ -11115,7 +11204,7 @@ size_t GeneratedCodeInfo_Annotation::ByteSizeLong() const {
}
cached_has_bits = _impl_._has_bits_[0];
if (cached_has_bits & 0x00000007u) {
if (cached_has_bits & 0x0000000fu) {
// optional string source_file = 2;
if (cached_has_bits & 0x00000001u) {
total_size += 1 +
@ -11133,6 +11222,12 @@ size_t GeneratedCodeInfo_Annotation::ByteSizeLong() const {
total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_end());
}
// optional .google.protobuf.GeneratedCodeInfo.Annotation.Semantic semantic = 5;
if (cached_has_bits & 0x00000008u) {
total_size += 1 +
::_pbi::WireFormatLite::EnumSize(this->_internal_semantic());
}
}
return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}
@ -11154,7 +11249,7 @@ void GeneratedCodeInfo_Annotation::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& t
_this->_impl_.path_.MergeFrom(from._impl_.path_);
cached_has_bits = from._impl_._has_bits_[0];
if (cached_has_bits & 0x00000007u) {
if (cached_has_bits & 0x0000000fu) {
if (cached_has_bits & 0x00000001u) {
_this->_internal_set_source_file(from._internal_source_file());
}
@ -11164,6 +11259,9 @@ void GeneratedCodeInfo_Annotation::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& t
if (cached_has_bits & 0x00000004u) {
_this->_impl_.end_ = from._impl_.end_;
}
if (cached_has_bits & 0x00000008u) {
_this->_impl_.semantic_ = from._impl_.semantic_;
}
_this->_impl_._has_bits_[0] |= cached_has_bits;
}
_this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
@ -11192,8 +11290,8 @@ void GeneratedCodeInfo_Annotation::InternalSwap(GeneratedCodeInfo_Annotation* ot
&other->_impl_.source_file_, rhs_arena
);
::PROTOBUF_NAMESPACE_ID::internal::memswap<
PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _impl_.end_)
+ sizeof(GeneratedCodeInfo_Annotation::_impl_.end_)
PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _impl_.semantic_)
+ sizeof(GeneratedCodeInfo_Annotation::_impl_.semantic_)
- PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _impl_.begin_)>(
reinterpret_cast<char*>(&_impl_.begin_),
reinterpret_cast<char*>(&other->_impl_.begin_));

@ -190,9 +190,9 @@ inline const std::string& FieldDescriptorProto_Type_Name(T enum_t_value) {
static_assert(::std::is_same<T, FieldDescriptorProto_Type>::value ||
::std::is_integral<T>::value,
"Incorrect type passed to function FieldDescriptorProto_Type_Name.");
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
FieldDescriptorProto_Type_descriptor(), enum_t_value);
return FieldDescriptorProto_Type_Name(static_cast<FieldDescriptorProto_Type>(enum_t_value));
}
template<> PROTOBUF_EXPORT const std::string& FieldDescriptorProto_Type_Name(FieldDescriptorProto_Type value);
inline bool FieldDescriptorProto_Type_Parse(
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FieldDescriptorProto_Type* value) {
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<FieldDescriptorProto_Type>(
@ -214,9 +214,9 @@ inline const std::string& FieldDescriptorProto_Label_Name(T enum_t_value) {
static_assert(::std::is_same<T, FieldDescriptorProto_Label>::value ||
::std::is_integral<T>::value,
"Incorrect type passed to function FieldDescriptorProto_Label_Name.");
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
FieldDescriptorProto_Label_descriptor(), enum_t_value);
return FieldDescriptorProto_Label_Name(static_cast<FieldDescriptorProto_Label>(enum_t_value));
}
template<> PROTOBUF_EXPORT const std::string& FieldDescriptorProto_Label_Name(FieldDescriptorProto_Label value);
inline bool FieldDescriptorProto_Label_Parse(
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FieldDescriptorProto_Label* value) {
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<FieldDescriptorProto_Label>(
@ -238,9 +238,9 @@ inline const std::string& FileOptions_OptimizeMode_Name(T enum_t_value) {
static_assert(::std::is_same<T, FileOptions_OptimizeMode>::value ||
::std::is_integral<T>::value,
"Incorrect type passed to function FileOptions_OptimizeMode_Name.");
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
FileOptions_OptimizeMode_descriptor(), enum_t_value);
return FileOptions_OptimizeMode_Name(static_cast<FileOptions_OptimizeMode>(enum_t_value));
}
template<> PROTOBUF_EXPORT const std::string& FileOptions_OptimizeMode_Name(FileOptions_OptimizeMode value);
inline bool FileOptions_OptimizeMode_Parse(
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FileOptions_OptimizeMode* value) {
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<FileOptions_OptimizeMode>(
@ -262,9 +262,9 @@ inline const std::string& FieldOptions_CType_Name(T enum_t_value) {
static_assert(::std::is_same<T, FieldOptions_CType>::value ||
::std::is_integral<T>::value,
"Incorrect type passed to function FieldOptions_CType_Name.");
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
FieldOptions_CType_descriptor(), enum_t_value);
return FieldOptions_CType_Name(static_cast<FieldOptions_CType>(enum_t_value));
}
template<> PROTOBUF_EXPORT const std::string& FieldOptions_CType_Name(FieldOptions_CType value);
inline bool FieldOptions_CType_Parse(
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FieldOptions_CType* value) {
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<FieldOptions_CType>(
@ -286,9 +286,9 @@ inline const std::string& FieldOptions_JSType_Name(T enum_t_value) {
static_assert(::std::is_same<T, FieldOptions_JSType>::value ||
::std::is_integral<T>::value,
"Incorrect type passed to function FieldOptions_JSType_Name.");
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
FieldOptions_JSType_descriptor(), enum_t_value);
return FieldOptions_JSType_Name(static_cast<FieldOptions_JSType>(enum_t_value));
}
template<> PROTOBUF_EXPORT const std::string& FieldOptions_JSType_Name(FieldOptions_JSType value);
inline bool FieldOptions_JSType_Parse(
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FieldOptions_JSType* value) {
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<FieldOptions_JSType>(
@ -310,14 +310,38 @@ inline const std::string& MethodOptions_IdempotencyLevel_Name(T enum_t_value) {
static_assert(::std::is_same<T, MethodOptions_IdempotencyLevel>::value ||
::std::is_integral<T>::value,
"Incorrect type passed to function MethodOptions_IdempotencyLevel_Name.");
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
MethodOptions_IdempotencyLevel_descriptor(), enum_t_value);
return MethodOptions_IdempotencyLevel_Name(static_cast<MethodOptions_IdempotencyLevel>(enum_t_value));
}
template<> PROTOBUF_EXPORT const std::string& MethodOptions_IdempotencyLevel_Name(MethodOptions_IdempotencyLevel value);
inline bool MethodOptions_IdempotencyLevel_Parse(
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, MethodOptions_IdempotencyLevel* value) {
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<MethodOptions_IdempotencyLevel>(
MethodOptions_IdempotencyLevel_descriptor(), name, value);
}
enum GeneratedCodeInfo_Annotation_Semantic : int {
GeneratedCodeInfo_Annotation_Semantic_NONE = 0,
GeneratedCodeInfo_Annotation_Semantic_SET = 1,
GeneratedCodeInfo_Annotation_Semantic_ALIAS = 2
};
PROTOBUF_EXPORT bool GeneratedCodeInfo_Annotation_Semantic_IsValid(int value);
constexpr GeneratedCodeInfo_Annotation_Semantic GeneratedCodeInfo_Annotation_Semantic_Semantic_MIN = GeneratedCodeInfo_Annotation_Semantic_NONE;
constexpr GeneratedCodeInfo_Annotation_Semantic GeneratedCodeInfo_Annotation_Semantic_Semantic_MAX = GeneratedCodeInfo_Annotation_Semantic_ALIAS;
constexpr int GeneratedCodeInfo_Annotation_Semantic_Semantic_ARRAYSIZE = GeneratedCodeInfo_Annotation_Semantic_Semantic_MAX + 1;
PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* GeneratedCodeInfo_Annotation_Semantic_descriptor();
template<typename T>
inline const std::string& GeneratedCodeInfo_Annotation_Semantic_Name(T enum_t_value) {
static_assert(::std::is_same<T, GeneratedCodeInfo_Annotation_Semantic>::value ||
::std::is_integral<T>::value,
"Incorrect type passed to function GeneratedCodeInfo_Annotation_Semantic_Name.");
return GeneratedCodeInfo_Annotation_Semantic_Name(static_cast<GeneratedCodeInfo_Annotation_Semantic>(enum_t_value));
}
template<> PROTOBUF_EXPORT const std::string& GeneratedCodeInfo_Annotation_Semantic_Name(GeneratedCodeInfo_Annotation_Semantic value);
inline bool GeneratedCodeInfo_Annotation_Semantic_Parse(
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, GeneratedCodeInfo_Annotation_Semantic* value) {
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<GeneratedCodeInfo_Annotation_Semantic>(
GeneratedCodeInfo_Annotation_Semantic_descriptor(), name, value);
}
// ===================================================================
class PROTOBUF_EXPORT FileDescriptorSet final :
@ -8285,6 +8309,38 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final :
// nested types ----------------------------------------------------
typedef GeneratedCodeInfo_Annotation_Semantic Semantic;
static constexpr Semantic NONE =
GeneratedCodeInfo_Annotation_Semantic_NONE;
static constexpr Semantic SET =
GeneratedCodeInfo_Annotation_Semantic_SET;
static constexpr Semantic ALIAS =
GeneratedCodeInfo_Annotation_Semantic_ALIAS;
static inline bool Semantic_IsValid(int value) {
return GeneratedCodeInfo_Annotation_Semantic_IsValid(value);
}
static constexpr Semantic Semantic_MIN =
GeneratedCodeInfo_Annotation_Semantic_Semantic_MIN;
static constexpr Semantic Semantic_MAX =
GeneratedCodeInfo_Annotation_Semantic_Semantic_MAX;
static constexpr int Semantic_ARRAYSIZE =
GeneratedCodeInfo_Annotation_Semantic_Semantic_ARRAYSIZE;
static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
Semantic_descriptor() {
return GeneratedCodeInfo_Annotation_Semantic_descriptor();
}
template<typename T>
static inline const std::string& Semantic_Name(T enum_t_value) {
static_assert(::std::is_same<T, Semantic>::value ||
::std::is_integral<T>::value,
"Incorrect type passed to function Semantic_Name.");
return GeneratedCodeInfo_Annotation_Semantic_Name(enum_t_value);
}
static inline bool Semantic_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name,
Semantic* value) {
return GeneratedCodeInfo_Annotation_Semantic_Parse(name, value);
}
// accessors -------------------------------------------------------
enum : int {
@ -8292,6 +8348,7 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final :
kSourceFileFieldNumber = 2,
kBeginFieldNumber = 3,
kEndFieldNumber = 4,
kSemanticFieldNumber = 5,
};
// repeated int32 path = 1 [packed = true];
int path_size() const;
@ -8359,6 +8416,19 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final :
void _internal_set_end(int32_t value);
public:
// optional .google.protobuf.GeneratedCodeInfo.Annotation.Semantic semantic = 5;
bool has_semantic() const;
private:
bool _internal_has_semantic() const;
public:
void clear_semantic();
::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic semantic() const;
void set_semantic(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic value);
private:
::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic _internal_semantic() const;
void _internal_set_semantic(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic value);
public:
// @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo.Annotation)
private:
class _Internal;
@ -8374,6 +8444,7 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final :
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr source_file_;
int32_t begin_;
int32_t end_;
int semantic_;
};
union { Impl_ _impl_; };
friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
@ -14696,6 +14767,35 @@ inline void GeneratedCodeInfo_Annotation::set_end(int32_t value) {
// @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.end)
}
// optional .google.protobuf.GeneratedCodeInfo.Annotation.Semantic semantic = 5;
inline bool GeneratedCodeInfo_Annotation::_internal_has_semantic() const {
bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
return value;
}
inline bool GeneratedCodeInfo_Annotation::has_semantic() const {
return _internal_has_semantic();
}
inline void GeneratedCodeInfo_Annotation::clear_semantic() {
_impl_.semantic_ = 0;
_impl_._has_bits_[0] &= ~0x00000008u;
}
inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic GeneratedCodeInfo_Annotation::_internal_semantic() const {
return static_cast< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic >(_impl_.semantic_);
}
inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic GeneratedCodeInfo_Annotation::semantic() const {
// @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.semantic)
return _internal_semantic();
}
inline void GeneratedCodeInfo_Annotation::_internal_set_semantic(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic value) {
assert(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic_IsValid(value));
_impl_._has_bits_[0] |= 0x00000008u;
_impl_.semantic_ = value;
}
inline void GeneratedCodeInfo_Annotation::set_semantic(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic value) {
_internal_set_semantic(value);
// @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.semantic)
}
// -------------------------------------------------------------------
// GeneratedCodeInfo
@ -14832,6 +14932,11 @@ template <>
inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel>() {
return ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel_descriptor();
}
template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic>() {
return ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic_descriptor();
}
PROTOBUF_NAMESPACE_CLOSE

@ -916,8 +916,20 @@ message GeneratedCodeInfo {
optional int32 begin = 3;
// 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).
optional int32 end = 4;
// Represents the identified object's effect on the element in the original
// .proto file.
enum Semantic {
// There is no effect or the effect is indescribable.
NONE = 0;
// The element is set or otherwise mutated.
SET = 1;
// An alias to the element is returned.
ALIAS = 2;
}
optional Semantic semantic = 5;
}
}

@ -35,6 +35,8 @@
#include <google/protobuf/generated_message_reflection.h>
#include <algorithm>
#include <atomic>
#include <cstdint>
#include <cstring>
#include <set>
@ -109,6 +111,31 @@ const std::string& NameOfEnum(const EnumDescriptor* descriptor, int value) {
return (d == nullptr ? GetEmptyString() : d->name());
}
// Internal helper routine for NameOfDenseEnum in the header file.
// Allocates and fills a simple array of string pointers, based on
// reflection information about the names of the enums. This routine
// allocates max_val + 1 entries, under the assumption that all the enums
// fall in the range [min_val .. max_val].
const std::string** MakeDenseEnumCache(const EnumDescriptor* desc, int min_val,
int max_val) {
auto* str_ptrs =
new const std::string*[static_cast<size_t>(max_val - min_val + 1)]();
const int count = desc->value_count();
for (int i = 0; i < count; ++i) {
const int num = desc->value(i)->number();
if (str_ptrs[num - min_val] == nullptr) {
// Don't over-write an existing entry, because in case of duplication, the
// first one wins.
str_ptrs[num - min_val] = &desc->value(i)->name();
}
}
// Change any unfilled entries to point to the empty string.
for (int i = 0; i < max_val - min_val + 1; ++i) {
if (str_ptrs[i] == nullptr) str_ptrs[i] = &GetEmptyStringAlreadyInited();
}
return str_ptrs;
}
} // namespace internal
// ===================================================================

@ -38,6 +38,8 @@
#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
#include <string>
#include <google/protobuf/stubs/casts.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
@ -368,6 +370,28 @@ struct PROTOBUF_EXPORT AddDescriptorsRunner {
explicit AddDescriptorsRunner(const DescriptorTable* table);
};
PROTOBUF_EXPORT const std::string** MakeDenseEnumCache(
const EnumDescriptor* desc, int min_val, int max_val);
// Similar to the routine NameOfEnum, this routine returns the name of an enum.
// Unlike that routine, it allocates, on-demand, a block of pointers to the
// std::string objects allocated by reflection to store the enum names. This
// way, as long as the enum values are fairly dense, looking them up can be
// very fast. This assumes all the enums fall in the range [min_val .. max_val].
template <const EnumDescriptor* (*descriptor_fn)(), int min_val, int max_val>
const std::string& NameOfDenseEnum(int v) {
static_assert(max_val - min_val >= 0, "Too mamny enums between min and max.");
if (PROTOBUF_PREDICT_TRUE(v >= min_val && v <= max_val)) {
// This is declared static inside the function so that it's allocated
// on-demand. Because this routine is templated, there is one of these
// caches per proto enum type.
static const std::string** cache =
MakeDenseEnumCache(descriptor_fn(), min_val, max_val);
return *cache[v - min_val];
}
return GetEmptyStringAlreadyInited();
}
} // namespace internal
} // namespace protobuf
} // namespace google

@ -53,6 +53,12 @@ class UnknownFieldSet;
namespace internal {
enum {
kInlinedStringAuxIdx = 0,
kSplitOffsetAuxIdx = 1,
kSplitSizeAuxIdx = 2,
};
// Field layout enums.
//
// Structural information about fields is packed into a 16-bit value. The enum

@ -1500,16 +1500,12 @@ bool TcParser::ChangeOneof(const TcParseTableBase* table,
}
namespace {
enum {
kSplitOffsetIdx = 2,
kSplitSizeIdx = 3,
};
uint32_t GetSplitOffset(const TcParseTableBase* table) {
return table->field_aux(kSplitOffsetIdx)->offset;
return table->field_aux(kSplitOffsetAuxIdx)->offset;
}
uint32_t GetSizeofSplit(const TcParseTableBase* table) {
return table->field_aux(kSplitSizeIdx)->offset;
return table->field_aux(kSplitSizeAuxIdx)->offset;
}
} // namespace

@ -829,6 +829,8 @@
#undef CREATE_NEW
#pragma push_macro("DELETE")
#undef DELETE
#pragma push_macro("DOMAIN")
#undef DOMAIN
#pragma push_macro("DOUBLE_CLICK")
#undef DOUBLE_CLICK
#pragma push_macro("ERROR")

@ -119,6 +119,7 @@
#ifdef _WIN32
#pragma pop_macro("CREATE_NEW")
#pragma pop_macro("DELETE")
#pragma pop_macro("DOMAIN")
#pragma pop_macro("DOUBLE_CLICK")
#pragma pop_macro("ERROR")
#pragma pop_macro("ERROR_BUSY")

@ -335,7 +335,7 @@ class RepeatedField final {
int total_size_;
// Replaces current_size_ with new_size and returns the previous value of
// current_size_. This function is indended to be the only place where
// 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_;

@ -650,7 +650,7 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase {
int total_size_;
// Replaces current_size_ with new_size and returns the previous value of
// current_size_. This function is indended to be the only place where
// 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_;

@ -176,6 +176,11 @@ const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* NullValue_descriptor() {
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fstruct_2eproto);
return file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto[0];
}
template<> PROTOBUF_EXPORT const std::string& NullValue_Name(
NullValue value) {
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum
<NullValue_descriptor, 0, 0>(static_cast<int>(value));
}
bool NullValue_IsValid(int value) {
switch (value) {
case 0:

@ -86,9 +86,9 @@ inline const std::string& NullValue_Name(T enum_t_value) {
static_assert(::std::is_same<T, NullValue>::value ||
::std::is_integral<T>::value,
"Incorrect type passed to function NullValue_Name.");
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
NullValue_descriptor(), enum_t_value);
return NullValue_Name(static_cast<NullValue>(enum_t_value));
}
template<> PROTOBUF_EXPORT const std::string& NullValue_Name(NullValue value);
inline bool NullValue_Parse(
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, NullValue* value) {
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<NullValue>(

@ -262,6 +262,11 @@ const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* Field_Kind_descriptor() {
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2ftype_2eproto);
return file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[0];
}
template<> PROTOBUF_EXPORT const std::string& Field_Kind_Name(
Field_Kind value) {
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum
<Field_Kind_descriptor, 0, 18>(static_cast<int>(value));
}
bool Field_Kind_IsValid(int value) {
switch (value) {
case 0:
@ -317,6 +322,11 @@ const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* Field_Cardinality_descriptor() {
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2ftype_2eproto);
return file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[1];
}
template<> PROTOBUF_EXPORT const std::string& Field_Cardinality_Name(
Field_Cardinality value) {
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum
<Field_Cardinality_descriptor, 0, 3>(static_cast<int>(value));
}
bool Field_Cardinality_IsValid(int value) {
switch (value) {
case 0:
@ -342,6 +352,11 @@ const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* Syntax_descriptor() {
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2ftype_2eproto);
return file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[2];
}
template<> PROTOBUF_EXPORT const std::string& Syntax_Name(
Syntax value) {
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum
<Syntax_descriptor, 0, 1>(static_cast<int>(value));
}
bool Syntax_IsValid(int value) {
switch (value) {
case 0:

@ -107,9 +107,9 @@ inline const std::string& Field_Kind_Name(T enum_t_value) {
static_assert(::std::is_same<T, Field_Kind>::value ||
::std::is_integral<T>::value,
"Incorrect type passed to function Field_Kind_Name.");
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
Field_Kind_descriptor(), enum_t_value);
return Field_Kind_Name(static_cast<Field_Kind>(enum_t_value));
}
template<> PROTOBUF_EXPORT const std::string& Field_Kind_Name(Field_Kind value);
inline bool Field_Kind_Parse(
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, Field_Kind* value) {
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<Field_Kind>(
@ -134,9 +134,9 @@ inline const std::string& Field_Cardinality_Name(T enum_t_value) {
static_assert(::std::is_same<T, Field_Cardinality>::value ||
::std::is_integral<T>::value,
"Incorrect type passed to function Field_Cardinality_Name.");
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
Field_Cardinality_descriptor(), enum_t_value);
return Field_Cardinality_Name(static_cast<Field_Cardinality>(enum_t_value));
}
template<> PROTOBUF_EXPORT const std::string& Field_Cardinality_Name(Field_Cardinality value);
inline bool Field_Cardinality_Parse(
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, Field_Cardinality* value) {
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<Field_Cardinality>(
@ -159,9 +159,9 @@ inline const std::string& Syntax_Name(T enum_t_value) {
static_assert(::std::is_same<T, Syntax>::value ||
::std::is_integral<T>::value,
"Incorrect type passed to function Syntax_Name.");
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
Syntax_descriptor(), enum_t_value);
return Syntax_Name(static_cast<Syntax>(enum_t_value));
}
template<> PROTOBUF_EXPORT const std::string& Syntax_Name(Syntax value);
inline bool Syntax_Parse(
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, Syntax* value) {
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<Syntax>(

@ -112,6 +112,20 @@ cc_test(
],
)
cc_library(
name = "zero_copy_sink",
srcs = ["zero_copy_sink.cc"],
hdrs = ["zero_copy_sink.h"],
copts = COPTS,
strip_include_prefix = "/src",
visibility = ["//visibility:private"],
deps = [
"//src/google/protobuf",
"//src/google/protobuf/io",
"//src/google/protobuf/stubs",
],
)
cc_library(
name = "json_util",
srcs = ["json_util.cc"],
@ -121,6 +135,7 @@ cc_library(
visibility = ["//:__subpackages__"],
deps = [
":type_resolver_util",
":zero_copy_sink",
"//src/google/protobuf",
"//src/google/protobuf/io",
"//src/google/protobuf/stubs",
@ -131,6 +146,18 @@ cc_library(
],
)
cc_test(
name = "zero_copy_sink_test",
srcs = ["zero_copy_sink_test.cc"],
copts = COPTS,
deps = [
":zero_copy_sink",
"//src/google/protobuf/stubs",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "json_util_test",
srcs = ["json_util_test.cc"],

@ -46,6 +46,7 @@ option java_outer_classname = "JsonFormatProto3";
enum EnumType {
FOO = 0;
BAR = 1;
TLSv1_2 = 2;
}
message MessageType {

@ -164,6 +164,7 @@ util::Status JsonToBinaryStream(TypeResolver* resolver,
options.case_insensitive_enum_parsing;
converter::ProtoStreamObjectWriter proto_writer(
resolver, type, &sink, &listener, proto_writer_options);
proto_writer.set_use_strict_base64_decoding(false);
converter::JsonStreamParser parser(&proto_writer);
const void* buffer;

@ -37,6 +37,10 @@
#include <string>
#include <vector>
#include <google/protobuf/duration.pb.h>
#include <google/protobuf/field_mask.pb.h>
#include <google/protobuf/struct.pb.h>
#include <google/protobuf/timestamp.pb.h>
#include <google/protobuf/wrappers.pb.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@ -163,14 +167,27 @@ INSTANTIATE_TEST_SUITE_P(JsonTestSuite, JsonTest,
TEST_P(JsonTest, TestWhitespaces) {
TestMessage m;
m.mutable_message_value();
m.set_string_value("foo");
m.add_repeated_bool_value(true);
m.add_repeated_bool_value(false);
EXPECT_THAT(ToJson(m), IsOkAndHolds("{\"messageValue\":{}}"));
EXPECT_THAT(
ToJson(m),
IsOkAndHolds(
R"({"stringValue":"foo","messageValue":{},"repeatedBoolValue":[true,false]})"));
JsonPrintOptions options;
options.add_whitespace = true;
EXPECT_THAT(ToJson(m, options), IsOkAndHolds("{\n"
" \"messageValue\": {}\n"
"}\n"));
// Note: whitespace here is significant.
EXPECT_THAT(ToJson(m, options), IsOkAndHolds(R"({
"stringValue": "foo",
"messageValue": {},
"repeatedBoolValue": [
true,
false
]
}
)"));
}
TEST_P(JsonTest, TestDefaultValues) {
@ -202,7 +219,6 @@ TEST_P(JsonTest, TestDefaultValues) {
"\"repeatedMessageValue\":[]"
"}"));
options.always_print_primitive_fields = true;
m.set_string_value("i am a test string value");
m.set_bytes_value("i am a test bytes value");
EXPECT_THAT(
@ -230,33 +246,28 @@ TEST_P(JsonTest, TestDefaultValues) {
"\"repeatedMessageValue\":[]"
"}"));
options.preserve_proto_field_names = true;
m.set_string_value("i am a test string value");
m.set_bytes_value("i am a test bytes value");
EXPECT_THAT(
ToJson(m, options),
IsOkAndHolds("{\"bool_value\":false,"
"\"int32_value\":0,"
"\"int64_value\":\"0\","
"\"uint32_value\":0,"
"\"uint64_value\":\"0\","
"\"float_value\":0,"
"\"double_value\":0,"
"\"string_value\":\"i am a test string value\","
"\"bytes_value\":\"aSBhbSBhIHRlc3QgYnl0ZXMgdmFsdWU=\","
"\"enum_value\":\"FOO\","
"\"repeated_bool_value\":[],"
"\"repeated_int32_value\":[],"
"\"repeated_int64_value\":[],"
"\"repeated_uint32_value\":[],"
"\"repeated_uint64_value\":[],"
"\"repeated_float_value\":[],"
"\"repeated_double_value\":[],"
"\"repeated_string_value\":[],"
"\"repeated_bytes_value\":[],"
"\"repeated_enum_value\":[],"
"\"repeated_message_value\":[]"
"}"));
ToJson(protobuf_unittest::TestAllTypes(), options),
IsOkAndHolds(
R"({"optionalInt32":0,"optionalInt64":"0","optionalUint32":0,)"
R"("optionalUint64":"0","optionalSint32":0,"optionalSint64":"0","optionalFixed32":0,)"
R"("optionalFixed64":"0","optionalSfixed32":0,"optionalSfixed64":"0",)"
R"("optionalFloat":0,"optionalDouble":0,"optionalBool":false,"optionalString":"",)"
R"("optionalBytes":"","optionalgroup":null,"optionalNestedEnum":"FOO","optionalForeignEnum":"FOREIGN_FOO",)"
R"("optionalImportEnum":"IMPORT_FOO","optionalStringPiece":"","optionalCord":"",)"
R"("repeatedInt32":[],"repeatedInt64":[],"repeatedUint32":[],"repeatedUint64":[],)"
R"("repeatedSint32":[],"repeatedSint64":[],"repeatedFixed32":[],"repeatedFixed64":[],)"
R"("repeatedSfixed32":[],"repeatedSfixed64":[],"repeatedFloat":[],"repeatedDouble":[],)"
R"("repeatedBool":[],"repeatedString":[],"repeatedBytes":[],"repeatedgroup":[],)"
R"("repeatedNestedMessage":[],"repeatedForeignMessage":[],"repeatedImportMessage":[],)"
R"("repeatedNestedEnum":[],"repeatedForeignEnum":[],"repeatedImportEnum":[],)"
R"("repeatedStringPiece":[],"repeatedCord":[],"repeatedLazyMessage":[],"defaultInt32":41,)"
R"("defaultInt64":"42","defaultUint32":43,"defaultUint64":"44","defaultSint32":-45,)"
R"("defaultSint64":"46","defaultFixed32":47,"defaultFixed64":"48","defaultSfixed32":49,)"
R"("defaultSfixed64":"-50","defaultFloat":51.5,"defaultDouble":52000,"defaultBool":true,)"
R"("defaultString":"hello","defaultBytes":"d29ybGQ=","defaultNestedEnum":"BAR",)"
R"("defaultForeignEnum":"FOREIGN_BAR","defaultImportEnum":"IMPORT_BAR",)"
R"("defaultStringPiece":"abc","defaultCord":"123"})"));
}
TEST_P(JsonTest, TestPreserveProtoFieldNames) {
@ -270,6 +281,7 @@ TEST_P(JsonTest, TestPreserveProtoFieldNames) {
JsonPrintOptions options;
options.preserve_proto_field_names = true;
EXPECT_THAT(ToJson(m, options), IsOkAndHolds("{\"message_value\":{}}"));
}
TEST_P(JsonTest, TestAlwaysPrintEnumsAsInts) {
@ -316,7 +328,7 @@ TEST_P(JsonTest, TestPrintEnumsAsIntsWithDefaultValue) {
EXPECT_EQ(parsed->enum_value3(), proto3::BAR);
}
TEST_P(JsonTest, DISABLED_TestPrintProto2EnumAsIntWithDefaultValue) {
TEST_P(JsonTest, TestPrintProto2EnumAsIntWithDefaultValue) {
protobuf_unittest::TestDefaultEnumValue orig;
JsonPrintOptions print_options;
@ -332,6 +344,15 @@ TEST_P(JsonTest, DISABLED_TestPrintProto2EnumAsIntWithDefaultValue) {
EXPECT_EQ(parsed->enum_value(), protobuf_unittest::DEFAULT);
}
TEST_P(JsonTest, WebSafeBytes) {
auto m = ToProto<TestMessage>(R"json({
"bytesValue": "-_"
})json");
ASSERT_OK(m);
EXPECT_EQ(m->bytes_value(), "\xfb");
}
TEST_P(JsonTest, ParseMessage) {
auto m = ToProto<TestMessage>(R"json(
{
@ -341,7 +362,7 @@ TEST_P(JsonTest, ParseMessage) {
"uint32Value": 42,
"uint64Value": 530242871653669,
"floatValue": 3.4e+38,
"doubleValue": -55.5,
"doubleValue": -55.3,
"stringValue": "foo bar baz",
"enumValue": "BAR",
"messageValue": {
@ -368,7 +389,11 @@ TEST_P(JsonTest, ParseMessage) {
EXPECT_EQ(m->uint32_value(), 42);
EXPECT_EQ(m->uint64_value(), 530242871653669);
EXPECT_EQ(m->float_value(), 3.4e+38f);
EXPECT_EQ(m->double_value(), -55.5);
EXPECT_EQ(m->double_value(),
-55.3); // This value is intentionally not a nice
// round number in base 2, so its floating point
// representation has many digits at the end, which
// printing back to JSON must handle well.
EXPECT_EQ(m->string_value(), "foo bar baz");
EXPECT_EQ(m->enum_value(), proto3::EnumType::BAR);
EXPECT_EQ(m->message_value().value(), 2048);
@ -406,13 +431,63 @@ TEST_P(JsonTest, ParseMessage) {
IsOkAndHolds(
R"({"boolValue":true,"int32Value":1234567891,"int64Value":"-5302428716536692736",)"
R"("uint32Value":42,"uint64Value":"530242871653669","floatValue":3.4e+38,)"
R"("doubleValue":-55.5,"stringValue":"foo bar baz","enumValue":"BAR",)"
R"("doubleValue":-55.3,"stringValue":"foo bar baz","enumValue":"BAR",)"
R"("messageValue":{"value":2048},"repeatedBoolValue":[true],"repeatedInt32Value":[0,-42])"
R"(,"repeatedUint64Value":["1","2"],"repeatedDoubleValue":[1.5,-2],)"
R"("repeatedStringValue":["foo","bar ",""],"repeatedEnumValue":["BAR","FOO"],)"
R"("repeatedMessageValue":[{"value":40},{"value":96}]})"));
}
TEST_P(JsonTest, CurseOfAtob) {
auto m = ToProto<TestMessage>(R"json(
{
repeatedBoolValue: ["0", "1", "false", "true", "f", "t", "no", "yes", "n", "y"]
}
)json");
ASSERT_OK(m);
EXPECT_EQ(m->repeated_bool_value_size(), 10);
EXPECT_FALSE(m->repeated_bool_value(0));
EXPECT_FALSE(m->repeated_bool_value(2));
EXPECT_FALSE(m->repeated_bool_value(4));
EXPECT_FALSE(m->repeated_bool_value(6));
EXPECT_FALSE(m->repeated_bool_value(8));
EXPECT_TRUE(m->repeated_bool_value(1));
EXPECT_TRUE(m->repeated_bool_value(3));
EXPECT_TRUE(m->repeated_bool_value(5));
EXPECT_TRUE(m->repeated_bool_value(7));
EXPECT_TRUE(m->repeated_bool_value(9));
}
TEST_P(JsonTest, ParseLegacySingleRepeatedField) {
auto m = ToProto<TestMessage>(R"json({
"repeatedInt32Value": 1997,
"repeatedStringValue": "oh no",
"repeatedEnumValue": "BAR",
"repeatedMessageValue": {"value": -1}
})json");
ASSERT_OK(m);
ASSERT_EQ(m->repeated_int32_value_size(), 1);
EXPECT_EQ(m->repeated_int32_value(0), 1997);
ASSERT_EQ(m->repeated_string_value_size(), 1);
EXPECT_EQ(m->repeated_string_value(0), "oh no");
ASSERT_EQ(m->repeated_enum_value_size(), 1);
EXPECT_EQ(m->repeated_enum_value(0), proto3::EnumType::BAR);
ASSERT_EQ(m->repeated_message_value_size(), 1);
EXPECT_EQ(m->repeated_message_value(0).value(), -1);
EXPECT_THAT(ToJson(*m),
IsOkAndHolds(R"({"repeatedInt32Value":[1997],)"
R"("repeatedStringValue":["oh no"],)"
R"("repeatedEnumValue":["BAR"],)"
R"("repeatedMessageValue":[{"value":-1}]})"));
}
TEST_P(JsonTest, ParseMap) {
TestMap message;
(*message.mutable_string_map())["hello"] = 1234;
@ -451,6 +526,15 @@ TEST_P(JsonTest, PrintPrimitiveOneof) {
IsOkAndHolds(R"({"oneofInt32Value":1})"));
}
TEST_P(JsonTest, ParseOverOneof) {
TestOneof m;
m.set_oneof_string_value("foo");
ASSERT_OK(ToProto(m, R"json({
"oneofInt32Value": 5,
})json"));
EXPECT_EQ(m.oneof_int32_value(), 5);
}
TEST_P(JsonTest, TestParseIgnoreUnknownFields) {
JsonParseOptions options;
options.ignore_unknown_fields = true;
@ -626,6 +710,19 @@ TEST_P(JsonTest, ParseWrappers) {
ToJson(*m),
IsOkAndHolds(
R"({"boolValue":true,"int32Value":42,"stringValue":"ieieo"})"));
auto m2 = ToProto<TestWrapper>(R"json(
{
"boolValue": { "value": true },
"int32Value": { "value": 42 },
"stringValue": { "value": "ieieo" },
}
)json");
ASSERT_OK(m2);
EXPECT_TRUE(m2->bool_value().value());
EXPECT_EQ(m2->int32_value().value(), 42);
EXPECT_EQ(m2->string_value().value(), "ieieo");
}
TEST_P(JsonTest, TestParsingUnknownAnyFields) {
@ -728,6 +825,15 @@ TEST_P(JsonTest, TestParsingEnumCaseSensitive) {
EXPECT_EQ(m.enum_value(), proto3::FOO);
}
TEST_P(JsonTest, TestParsingEnumLowercase) {
JsonParseOptions options;
options.case_insensitive_enum_parsing = true;
auto m = ToProto<TestMessage>(R"json({"enum_value": "TLSv1_2"})json", options);
ASSERT_OK(m);
EXPECT_THAT(m->enum_value(), proto3::TLSv1_2);
}
TEST_P(JsonTest, TestParsingEnumIgnoreCase) {
TestMessage m;
m.set_enum_value(proto3::FOO);
@ -738,6 +844,135 @@ TEST_P(JsonTest, TestParsingEnumIgnoreCase) {
EXPECT_EQ(m.enum_value(), proto3::BAR);
}
// Parsing does NOT work like MergeFrom: existing repeated field values are
// clobbered, not appended to.
TEST_P(JsonTest, TestOverwriteRepeated) {
TestMessage m;
m.add_repeated_int32_value(5);
ASSERT_OK(ToProto(m, R"json({"repeated_int32_value": [1, 2, 3]})json"));
EXPECT_EQ(m.repeated_int32_value_size(), 3);
EXPECT_EQ(m.repeated_int32_value(0), 1);
EXPECT_EQ(m.repeated_int32_value(1), 2);
EXPECT_EQ(m.repeated_int32_value(2), 3);
}
TEST_P(JsonTest, TestDuration) {
auto m = ToProto<proto3::TestDuration>(R"json(
{
"value": "123456.789s",
"repeated_value": ["0.1s", "999s"]
}
)json");
ASSERT_OK(m);
EXPECT_EQ(m->value().seconds(), 123456);
EXPECT_EQ(m->value().nanos(), 789000000);
EXPECT_EQ(m->repeated_value().size(), 2);
EXPECT_EQ(m->repeated_value(0).seconds(), 0);
EXPECT_EQ(m->repeated_value(0).nanos(), 100000000);
EXPECT_EQ(m->repeated_value(1).seconds(), 999);
EXPECT_EQ(m->repeated_value(1).nanos(), 0);
EXPECT_THAT(
ToJson(*m),
IsOkAndHolds(
R"({"value":"123456.789s","repeatedValue":["0.100s","999s"]})"));
auto m2 = ToProto<proto3::TestDuration>(R"json(
{
"value": {"seconds": 4, "nanos": 5},
}
)json");
ASSERT_OK(m2);
EXPECT_EQ(m2->value().seconds(), 4);
EXPECT_EQ(m2->value().nanos(), 5);
}
// These tests are not exhaustive; tests in //third_party/protobuf/conformance
// are more comprehensive.
TEST_P(JsonTest, TestTimestamp) {
auto m = ToProto<proto3::TestTimestamp>(R"json(
{
"value": "1996-02-27T12:00:00Z",
"repeated_value": ["9999-12-31T23:59:59Z"]
}
)json");
ASSERT_OK(m);
EXPECT_EQ(m->value().seconds(), 825422400);
EXPECT_EQ(m->value().nanos(), 0);
EXPECT_EQ(m->repeated_value().size(), 1);
EXPECT_EQ(m->repeated_value(0).seconds(), 253402300799);
EXPECT_EQ(m->repeated_value(0).nanos(), 0);
EXPECT_THAT(
ToJson(*m),
IsOkAndHolds(
R"({"value":"1996-02-27T12:00:00Z","repeatedValue":["9999-12-31T23:59:59Z"]})"));
auto m2 = ToProto<proto3::TestTimestamp>(R"json(
{
"value": {"seconds": 4, "nanos": 5},
}
)json");
ASSERT_OK(m2);
EXPECT_EQ(m2->value().seconds(), 4);
EXPECT_EQ(m2->value().nanos(), 5);
}
// This test case comes from Envoy's tests. They like to parse a Value out of
// YAML, turn it into JSON, and then parse it as a different proto. This means
// we must be extremely careful with integer fields, because they need to
// round-trip through doubles. This happens all over Envoy. :(
TEST_P(JsonTest, TestEnvoyRoundTrip) {
auto m = ToProto<google::protobuf::Value>(R"json(
{
"value": {"seconds": 1234567891, "nanos": 234000000},
}
)json");
ASSERT_OK(m);
auto j = ToJson(*m);
ASSERT_OK(j);
auto m2 = ToProto<proto3::TestTimestamp>(*j);
ASSERT_OK(m2);
EXPECT_EQ(m2->value().seconds(), 1234567891);
EXPECT_EQ(m2->value().nanos(), 234000000);
}
TEST_P(JsonTest, TestFieldMask) {
auto m = ToProto<proto3::TestFieldMask>(R"json(
{
"value": "foo,bar.bazBaz"
}
)json");
ASSERT_OK(m);
EXPECT_EQ(m->value().paths_size(), 2);
EXPECT_EQ(m->value().paths(0), "foo");
EXPECT_EQ(m->value().paths(1), "bar.baz_baz");
EXPECT_THAT(ToJson(*m), IsOkAndHolds(R"({"value":"foo,bar.bazBaz"})"));
auto m2 = ToProto<proto3::TestFieldMask>(R"json(
{
"value": {
"paths": ["yep.really"]
},
}
)json");
ASSERT_OK(m2);
EXPECT_EQ(m2->value().paths_size(), 1);
EXPECT_EQ(m2->value().paths(0), "yep.really");
}
TEST_P(JsonTest, DISABLED_HtmlEscape) {
TestMessage m;
m.set_string_value("</script>");

Loading…
Cancel
Save