Merge tag 'refs/tags/sync-piper' into sync-stage

# Conflicts:
#	java/kotlin/src/test/kotlin/com/google/protobuf/Proto2Test.kt
#	src/google/protobuf/repeated_field_unittest.cc
pull/8617/head
Deanna Garcia 4 years ago
commit f66dea481d
  1. 2
      conformance/binary_json_conformance_suite.h
  2. 2
      conformance/text_format_conformance_suite.h
  3. 34
      java/kotlin-lite/src/test/kotlin/com/google/protobuf/ExtendableMessageLiteExtensionsTest.kt
  4. 74
      java/kotlin-lite/src/test/kotlin/com/google/protobuf/Proto2LiteTest.kt
  5. 32
      java/kotlin/src/main/kotlin/com/google/protobuf/DslList.kt
  6. 32
      java/kotlin/src/main/kotlin/com/google/protobuf/DslMap.kt
  7. 30
      java/kotlin/src/main/kotlin/com/google/protobuf/DslProxy.kt
  8. 30
      java/kotlin/src/main/kotlin/com/google/protobuf/ExtendableMessageExtensions.kt
  9. 30
      java/kotlin/src/main/kotlin/com/google/protobuf/ExtendableMessageLiteExtensions.kt
  10. 30
      java/kotlin/src/main/kotlin/com/google/protobuf/ExtensionList.kt
  11. 30
      java/kotlin/src/main/kotlin/com/google/protobuf/OnlyForUseByGeneratedProtoCode.kt
  12. 30
      java/kotlin/src/main/kotlin/com/google/protobuf/ProtoDslMarker.kt
  13. 30
      java/kotlin/src/main/kotlin/com/google/protobuf/UnmodifiableCollections.kt
  14. 30
      java/kotlin/src/test/kotlin/com/google/protobuf/DslListTest.kt
  15. 30
      java/kotlin/src/test/kotlin/com/google/protobuf/DslMapTest.kt
  16. 34
      java/kotlin/src/test/kotlin/com/google/protobuf/ExtendableMessageExtensionsTest.kt
  17. 34
      java/kotlin/src/test/kotlin/com/google/protobuf/ExtensionListTest.kt
  18. 82
      java/kotlin/src/test/kotlin/com/google/protobuf/Proto2Test.kt
  19. 87
      java/kotlin/src/test/kotlin/com/google/protobuf/Proto3Test.kt
  20. 37
      java/kotlin/src/test/proto/com/google/protobuf/evil_names_proto2.proto
  21. 37
      java/kotlin/src/test/proto/com/google/protobuf/evil_names_proto3.proto
  22. 34
      java/kotlin/src/test/proto/com/google/protobuf/example_extensible_message.proto
  23. 34
      java/kotlin/src/test/proto/com/google/protobuf/multiple_files_proto3.proto
  24. 6
      java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
  25. 59
      python/google/protobuf/internal/python_protobuf.cc
  26. 19
      python/google/protobuf/pyext/message.cc
  27. 57
      python/google/protobuf/python_protobuf.h
  28. 32
      python/setup.py
  29. 47
      src/google/protobuf/any.pb.cc
  30. 23
      src/google/protobuf/any.pb.h
  31. 141
      src/google/protobuf/api.pb.cc
  32. 91
      src/google/protobuf/api.pb.h
  33. 40
      src/google/protobuf/arena.h
  34. 195
      src/google/protobuf/arena_unittest.cc
  35. 21
      src/google/protobuf/arenastring.h
  36. 12
      src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
  37. 24
      src/google/protobuf/compiler/cpp/cpp_enum_field.cc
  38. 24
      src/google/protobuf/compiler/cpp/cpp_field.cc
  39. 9
      src/google/protobuf/compiler/cpp/cpp_file.cc
  40. 6
      src/google/protobuf/compiler/cpp/cpp_helpers.cc
  41. 16
      src/google/protobuf/compiler/cpp/cpp_helpers.h
  42. 4
      src/google/protobuf/compiler/cpp/cpp_map_field.cc
  43. 23
      src/google/protobuf/compiler/cpp/cpp_map_field.h
  44. 246
      src/google/protobuf/compiler/cpp/cpp_message.cc
  45. 46
      src/google/protobuf/compiler/cpp/cpp_message_field.cc
  46. 1
      src/google/protobuf/compiler/cpp/cpp_options.h
  47. 561
      src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc
  48. 84
      src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h
  49. 18
      src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
  50. 65
      src/google/protobuf/compiler/cpp/cpp_string_field.cc
  51. 4
      src/google/protobuf/compiler/importer.h
  52. 84
      src/google/protobuf/compiler/java/java_enum_field.h
  53. 44
      src/google/protobuf/compiler/java/java_enum_field_lite.h
  54. 14
      src/google/protobuf/compiler/java/java_field.cc
  55. 2
      src/google/protobuf/compiler/java/java_file.cc
  56. 87
      src/google/protobuf/compiler/java/java_helpers.cc
  57. 46
      src/google/protobuf/compiler/java/java_kotlin_generator.cc
  58. 40
      src/google/protobuf/compiler/java/java_kotlin_generator.h
  59. 37
      src/google/protobuf/compiler/java/java_map_field.h
  60. 18
      src/google/protobuf/compiler/java/java_map_field_lite.h
  61. 35
      src/google/protobuf/compiler/java/java_message.cc
  62. 13
      src/google/protobuf/compiler/java/java_message.h
  63. 41
      src/google/protobuf/compiler/java/java_message_field.h
  64. 18
      src/google/protobuf/compiler/java/java_message_field_lite.h
  65. 23
      src/google/protobuf/compiler/java/java_name_resolver.cc
  66. 6
      src/google/protobuf/compiler/java/java_name_resolver.h
  67. 1
      src/google/protobuf/compiler/java/java_primitive_field.cc
  68. 84
      src/google/protobuf/compiler/java/java_primitive_field.h
  69. 38
      src/google/protobuf/compiler/java/java_primitive_field_lite.h
  70. 41
      src/google/protobuf/compiler/java/java_string_field.h
  71. 44
      src/google/protobuf/compiler/java/java_string_field_lite.h
  72. 188
      src/google/protobuf/compiler/plugin.pb.cc
  73. 105
      src/google/protobuf/compiler/plugin.pb.h
  74. 1287
      src/google/protobuf/descriptor.pb.cc
  75. 675
      src/google/protobuf/descriptor.pb.h
  76. 47
      src/google/protobuf/duration.pb.cc
  77. 13
      src/google/protobuf/duration.pb.h
  78. 47
      src/google/protobuf/empty.pb.cc
  79. 13
      src/google/protobuf/empty.pb.h
  80. 91
      src/google/protobuf/extension_set.cc
  81. 13
      src/google/protobuf/extension_set.h
  82. 47
      src/google/protobuf/field_mask.pb.cc
  83. 20
      src/google/protobuf/field_mask.pb.h
  84. 398
      src/google/protobuf/generated_message_reflection.cc
  85. 170
      src/google/protobuf/generated_message_reflection_unittest.cc
  86. 123
      src/google/protobuf/generated_message_tctable_decl.h
  87. 53
      src/google/protobuf/generated_message_tctable_full.cc
  88. 245
      src/google/protobuf/generated_message_tctable_impl.h
  89. 91
      src/google/protobuf/generated_message_tctable_impl.inc
  90. 148
      src/google/protobuf/generated_message_tctable_lite.cc
  91. 3
      src/google/protobuf/generated_message_util.cc
  92. 5
      src/google/protobuf/map_field.cc
  93. 4
      src/google/protobuf/map_field.h
  94. 8
      src/google/protobuf/map_field_inl.h
  95. 61
      src/google/protobuf/message.cc
  96. 52
      src/google/protobuf/message.h
  97. 10
      src/google/protobuf/message_lite.h
  98. 54
      src/google/protobuf/metadata_lite.h
  99. 50
      src/google/protobuf/parse_context.cc
  100. 51
      src/google/protobuf/parse_context.h
  101. Some files were not shown because too many files have changed in this diff Show More

@ -42,7 +42,7 @@ class BinaryAndJsonConformanceSuite : public ConformanceTestSuite {
BinaryAndJsonConformanceSuite() {}
private:
void RunSuiteImpl();
void RunSuiteImpl() override;
void RunJsonTests();
void RunJsonTestsForFieldNameConvention();
void RunJsonTestsForNonRepeatedTypes();

@ -41,7 +41,7 @@ class TextFormatConformanceTestSuite : public ConformanceTestSuite {
TextFormatConformanceTestSuite();
private:
void RunSuiteImpl();
void RunSuiteImpl() override;
void RunValidTextFormatTest(const std::string& test_name,
ConformanceLevel level, const std::string& input);
void RunValidTextFormatTestProto2(const std::string& test_name,

@ -1,8 +1,38 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf.kotlin
import com.google.common.truth.Truth.assertThat
import example_extensible_message.ExampleExtensibleMessage
import example_extensible_message.ExampleExtensibleMessageOuterClass as TestProto
import com.google.protobuf.kotlin.test.ExampleExtensibleMessage
import com.google.protobuf.kotlin.test.ExampleExtensibleMessageOuterClass as TestProto
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4

@ -1,3 +1,33 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf.kotlin
import com.google.common.truth.Truth.assertThat
@ -16,13 +46,13 @@ import com.google.protobuf.UnittestLite.TestEmptyMessageLite
import com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite
import com.google.protobuf.copy
import com.google.protobuf.foreignMessageLite
import evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2
import evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes
import evil_names_proto2.EvilNamesProto2OuterClass.Interface
import evil_names_proto2.HardKeywordsAllTypesKt
import evil_names_proto2.evilNamesProto2
import evil_names_proto2.hardKeywordsAllTypes
import evil_names_proto2.interface_
import com.google.protobuf.kotlin.generator.EvilNamesProto2OuterClass.EvilNamesProto2
import com.google.protobuf.kotlin.generator.EvilNamesProto2OuterClass.HardKeywordsAllTypesProto2
import com.google.protobuf.kotlin.generator.EvilNamesProto2OuterClass.Interface
import com.google.protobuf.kotlin.generator.HardKeywordsAllTypesProto2Kt
import com.google.protobuf.kotlin.generator.evilNamesProto2
import com.google.protobuf.kotlin.generator.hardKeywordsAllTypesProto2
import com.google.protobuf.kotlin.generator.interface_
import com.google.protobuf.optionalGroupExtensionLite
import com.google.protobuf.repeatedGroupExtensionLite
import com.google.protobuf.testAllExtensionsLite
@ -918,18 +948,18 @@ class Proto2LiteTest {
@Test
fun testHardKeywordGettersAndSetters() {
hardKeywordsAllTypes {
hardKeywordsAllTypesProto2 {
as_ = 1
assertThat(as_).isEqualTo(1)
in_ = "foo"
assertThat(in_).isEqualTo("foo")
break_ = HardKeywordsAllTypes.NestedEnum.FOO
assertThat(break_).isEqualTo(HardKeywordsAllTypes.NestedEnum.FOO)
break_ = HardKeywordsAllTypesProto2.NestedEnum.FOO
assertThat(break_).isEqualTo(HardKeywordsAllTypesProto2.NestedEnum.FOO)
do_ = HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }
assertThat(do_).isEqualTo(HardKeywordsAllTypesKt.nestedMessage { while_ = 1 })
do_ = HardKeywordsAllTypesProto2Kt.nestedMessage { while_ = 1 }
assertThat(do_).isEqualTo(HardKeywordsAllTypesProto2Kt.nestedMessage { while_ = 1 })
continue_[1] = 1
assertThat(continue_[1]).isEqualTo(1)
@ -940,34 +970,34 @@ class Proto2LiteTest {
for_ += "foo"
assertThat(for_).isEqualTo(listOf("foo"))
fun_ += HardKeywordsAllTypes.NestedEnum.FOO
assertThat(fun_).isEqualTo(listOf(HardKeywordsAllTypes.NestedEnum.FOO))
fun_ += HardKeywordsAllTypesProto2.NestedEnum.FOO
assertThat(fun_).isEqualTo(listOf(HardKeywordsAllTypesProto2.NestedEnum.FOO))
if_ += HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }
assertThat(if_).isEqualTo(listOf(HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }))
if_ += HardKeywordsAllTypesProto2Kt.nestedMessage { while_ = 1 }
assertThat(if_).isEqualTo(listOf(HardKeywordsAllTypesProto2Kt.nestedMessage { while_ = 1 }))
}
}
@Test
fun testHardKeywordHazzers() {
hardKeywordsAllTypes {
hardKeywordsAllTypesProto2 {
as_ = 1
assertThat(hasAs_()).isTrue()
in_ = "foo"
assertThat(hasIn_()).isTrue()
break_ = HardKeywordsAllTypes.NestedEnum.FOO
break_ = HardKeywordsAllTypesProto2.NestedEnum.FOO
assertThat(hasBreak_()).isTrue()
do_ = HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }
do_ = HardKeywordsAllTypesProto2Kt.nestedMessage { while_ = 1 }
assertThat(hasDo_()).isTrue()
}
}
@Test
fun testHardKeywordClears() {
hardKeywordsAllTypes {
hardKeywordsAllTypesProto2 {
as_ = 1
clearAs_()
assertThat(hasAs_()).isFalse()
@ -976,11 +1006,11 @@ class Proto2LiteTest {
clearIn_()
assertThat(hasIn_()).isFalse()
break_ = HardKeywordsAllTypes.NestedEnum.FOO
break_ = HardKeywordsAllTypesProto2.NestedEnum.FOO
clearBreak_()
assertThat(hasBreak_()).isFalse()
do_ = HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }
do_ = HardKeywordsAllTypesProto2Kt.nestedMessage { while_ = 1 }
clearDo_()
assertThat(hasDo_()).isFalse()
}

@ -1,3 +1,33 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf.kotlin
/**
@ -25,3 +55,5 @@ class DslList<E, P : DslProxy> @OnlyForUseByGeneratedProtoCode constructor(
override fun toString(): String = delegate.toString()
}
// TODO(lowasser): investigate making this an inline class

@ -1,3 +1,33 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf.kotlin
/**
@ -28,3 +58,5 @@ class DslMap<K, V, P : DslProxy> @OnlyForUseByGeneratedProtoCode constructor(
override fun toString(): String = delegate.toString()
}
// TODO(lowasser): investigate making this an inline class

@ -1,3 +1,33 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf.kotlin
/**

@ -1,3 +1,33 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf.kotlin
import com.google.protobuf.ExtensionLite

@ -1,3 +1,33 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf.kotlin
import com.google.protobuf.ExtensionLite

@ -1,3 +1,33 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf.kotlin
import com.google.protobuf.ExtensionLite

@ -1,3 +1,33 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf.kotlin
/**

@ -1,3 +1,33 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf.kotlin
/**

@ -1,3 +1,33 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf.kotlin
/** Wraps an [Iterator] and makes it unmodifiable even from Java. */

@ -1,3 +1,33 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf.kotlin
import com.google.common.testing.EqualsTester

@ -1,3 +1,33 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf.kotlin
import com.google.common.testing.EqualsTester

@ -1,8 +1,38 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf.kotlin
import com.google.common.truth.Truth.assertThat
import example_extensible_message.ExampleExtensibleMessage
import example_extensible_message.ExampleExtensibleMessageOuterClass as TestProto
import com.google.protobuf.kotlin.test.ExampleExtensibleMessage
import com.google.protobuf.kotlin.test.ExampleExtensibleMessageOuterClass as TestProto
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4

@ -1,9 +1,39 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf.kotlin
import com.google.common.testing.EqualsTester
import com.google.common.truth.Truth.assertThat
import example_extensible_message.ExampleExtensibleMessage
import example_extensible_message.ExampleExtensibleMessageOuterClass as TestProto
import com.google.protobuf.kotlin.test.ExampleExtensibleMessage
import com.google.protobuf.kotlin.test.ExampleExtensibleMessageOuterClass as TestProto
import kotlin.test.assertFailsWith
import org.junit.Test
import org.junit.runner.RunWith

@ -1,15 +1,45 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf.kotlin
import com.google.common.truth.Truth.assertThat
import com.google.protobuf.TestUtil
import com.google.protobuf.TestUtil.toBytes
import evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2
import evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes
import evil_names_proto2.EvilNamesProto2OuterClass.Interface
import evil_names_proto2.HardKeywordsAllTypesKt
import evil_names_proto2.evilNamesProto2
import evil_names_proto2.hardKeywordsAllTypes
import evil_names_proto2.interface_
import com.google.protobuf.kotlin.generator.EvilNamesProto2OuterClass.EvilNamesProto2
import com.google.protobuf.kotlin.generator.EvilNamesProto2OuterClass.HardKeywordsAllTypesProto2
import com.google.protobuf.kotlin.generator.EvilNamesProto2OuterClass.Interface
import com.google.protobuf.kotlin.generator.HardKeywordsAllTypesProto2Kt
import com.google.protobuf.kotlin.generator.evilNamesProto2
import com.google.protobuf.kotlin.generator.hardKeywordsAllTypesProto2
import com.google.protobuf.kotlin.generator.interface_
import com.google.protobuf.test.UnittestImport.ImportEnum
import com.google.protobuf.test.UnittestImport.ImportMessage
import com.google.protobuf.test.UnittestImportPublic.PublicImportMessage
@ -465,12 +495,20 @@ class Proto2Test {
this[UnittestProto.repeatedBytesExtension] += toBytes("316")
this[UnittestProto.repeatedGroupExtension] += repeatedGroupExtension { a = 317 }
this[UnittestProto.repeatedNestedMessageExtension] +=
<<<<<<< HEAD
TestAllTypesKt.nestedMessage { bb = 318 }
=======
TestAllTypesKt.nestedMessage { bb = 318 }
>>>>>>> refs/tags/sync-piper
this[UnittestProto.repeatedForeignMessageExtension] += foreignMessage { c = 319 }
this[UnittestProto.repeatedImportMessageExtension] +=
ImportMessage.newBuilder().setD(320).build()
this[UnittestProto.repeatedLazyMessageExtension] +=
<<<<<<< HEAD
TestAllTypesKt.nestedMessage { bb = 327 }
=======
TestAllTypesKt.nestedMessage { bb = 327 }
>>>>>>> refs/tags/sync-piper
this[UnittestProto.repeatedNestedEnumExtension] += NestedEnum.BAZ
this[UnittestProto.repeatedForeignEnumExtension] += ForeignEnum.FOREIGN_BAZ
this[UnittestProto.repeatedImportEnumExtension] += ImportEnum.IMPORT_BAZ
@ -910,18 +948,18 @@ class Proto2Test {
@Test
fun testHardKeywordGettersAndSetters() {
hardKeywordsAllTypes {
hardKeywordsAllTypesProto2 {
as_ = 1
assertThat(as_).isEqualTo(1)
in_ = "foo"
assertThat(in_).isEqualTo("foo")
break_ = HardKeywordsAllTypes.NestedEnum.FOO
assertThat(break_).isEqualTo(HardKeywordsAllTypes.NestedEnum.FOO)
break_ = HardKeywordsAllTypesProto2.NestedEnum.FOO
assertThat(break_).isEqualTo(HardKeywordsAllTypesProto2.NestedEnum.FOO)
do_ = HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }
assertThat(do_).isEqualTo(HardKeywordsAllTypesKt.nestedMessage { while_ = 1 })
do_ = HardKeywordsAllTypesProto2Kt.nestedMessage { while_ = 1 }
assertThat(do_).isEqualTo(HardKeywordsAllTypesProto2Kt.nestedMessage { while_ = 1 })
continue_[1] = 1
assertThat(continue_[1]).isEqualTo(1)
@ -932,34 +970,34 @@ class Proto2Test {
for_ += "foo"
assertThat(for_).isEqualTo(listOf("foo"))
fun_ += HardKeywordsAllTypes.NestedEnum.FOO
assertThat(fun_).isEqualTo(listOf(HardKeywordsAllTypes.NestedEnum.FOO))
fun_ += HardKeywordsAllTypesProto2.NestedEnum.FOO
assertThat(fun_).isEqualTo(listOf(HardKeywordsAllTypesProto2.NestedEnum.FOO))
if_ += HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }
assertThat(if_).isEqualTo(listOf(HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }))
if_ += HardKeywordsAllTypesProto2Kt.nestedMessage { while_ = 1 }
assertThat(if_).isEqualTo(listOf(HardKeywordsAllTypesProto2Kt.nestedMessage { while_ = 1 }))
}
}
@Test
fun testHardKeywordHazzers() {
hardKeywordsAllTypes {
hardKeywordsAllTypesProto2 {
as_ = 1
assertThat(hasAs_()).isTrue()
in_ = "foo"
assertThat(hasIn_()).isTrue()
break_ = HardKeywordsAllTypes.NestedEnum.FOO
break_ = HardKeywordsAllTypesProto2.NestedEnum.FOO
assertThat(hasBreak_()).isTrue()
do_ = HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }
do_ = HardKeywordsAllTypesProto2Kt.nestedMessage { while_ = 1 }
assertThat(hasDo_()).isTrue()
}
}
@Test
fun testHardKeywordClears() {
hardKeywordsAllTypes {
hardKeywordsAllTypesProto2 {
as_ = 1
clearAs_()
assertThat(hasAs_()).isFalse()
@ -968,11 +1006,11 @@ class Proto2Test {
clearIn_()
assertThat(hasIn_()).isFalse()
break_ = HardKeywordsAllTypes.NestedEnum.FOO
break_ = HardKeywordsAllTypesProto2.NestedEnum.FOO
clearBreak_()
assertThat(hasBreak_()).isFalse()
do_ = HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }
do_ = HardKeywordsAllTypesProto2Kt.nestedMessage { while_ = 1 }
clearDo_()
assertThat(hasDo_()).isFalse()
}

@ -1,18 +1,43 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf.kotlin
import com.google.common.truth.Truth.assertThat
import evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3
import evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes
import evil_names_proto3.EvilNamesProto3OuterClass.Class
import evil_names_proto3.HardKeywordsAllTypesKt
import evil_names_proto3.class_
import evil_names_proto3.evilNamesProto3
import evil_names_proto3.hardKeywordsAllTypes
import multiple_files_proto3.MultipleFilesMessageA
import multiple_files_proto3.MultipleFilesMessageB
import multiple_files_proto3.multipleFilesMessageA
import multiple_files_proto3.multipleFilesMessageB
import proto3_unittest.UnittestProto3
import com.google.protobuf.kotlin.generator.EvilNamesProto3OuterClass.Class
import com.google.protobuf.kotlin.generator.EvilNamesProto3OuterClass.EvilNamesProto3
import com.google.protobuf.kotlin.generator.EvilNamesProto3OuterClass.HardKeywordsAllTypesProto3
import com.google.protobuf.kotlin.generator.HardKeywordsAllTypesProto3Kt
import com.google.protobuf.kotlin.generator.class_
import com.google.protobuf.kotlin.generator.evilNamesProto3
import com.google.protobuf.kotlin.generator.hardKeywordsAllTypesProto3
import proto3_unittest.TestAllTypesKt
import proto3_unittest.TestAllTypesKt.nestedMessage
import proto3_unittest.UnittestProto3.TestAllTypes
@ -255,18 +280,18 @@ class Proto3Test {
@Test
fun testHardKeywordGettersAndSetters() {
hardKeywordsAllTypes {
hardKeywordsAllTypesProto3 {
as_ = 1
assertThat(as_).isEqualTo(1)
in_ = "foo"
assertThat(in_).isEqualTo("foo")
break_ = HardKeywordsAllTypes.NestedEnum.FOO
assertThat(break_).isEqualTo(HardKeywordsAllTypes.NestedEnum.FOO)
break_ = HardKeywordsAllTypesProto3.NestedEnum.FOO
assertThat(break_).isEqualTo(HardKeywordsAllTypesProto3.NestedEnum.FOO)
do_ = HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }
assertThat(do_).isEqualTo(HardKeywordsAllTypesKt.nestedMessage { while_ = 1 })
do_ = HardKeywordsAllTypesProto3Kt.nestedMessage { while_ = 1 }
assertThat(do_).isEqualTo(HardKeywordsAllTypesProto3Kt.nestedMessage { while_ = 1 })
continue_[1] = 1
assertThat(continue_[1]).isEqualTo(1)
@ -277,34 +302,34 @@ class Proto3Test {
for_ += "foo"
assertThat(for_).isEqualTo(listOf("foo"))
fun_ += HardKeywordsAllTypes.NestedEnum.FOO
assertThat(fun_).isEqualTo(listOf(HardKeywordsAllTypes.NestedEnum.FOO))
fun_ += HardKeywordsAllTypesProto3.NestedEnum.FOO
assertThat(fun_).isEqualTo(listOf(HardKeywordsAllTypesProto3.NestedEnum.FOO))
if_ += HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }
assertThat(if_).isEqualTo(listOf(HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }))
if_ += HardKeywordsAllTypesProto3Kt.nestedMessage { while_ = 1 }
assertThat(if_).isEqualTo(listOf(HardKeywordsAllTypesProto3Kt.nestedMessage { while_ = 1 }))
}
}
@Test
fun testHardKeywordHazzers() {
hardKeywordsAllTypes {
hardKeywordsAllTypesProto3 {
as_ = 1
assertThat(hasAs_()).isTrue()
in_ = "foo"
assertThat(hasIn_()).isTrue()
break_ = HardKeywordsAllTypes.NestedEnum.FOO
break_ = HardKeywordsAllTypesProto3.NestedEnum.FOO
assertThat(hasBreak_()).isTrue()
do_ = HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }
do_ = HardKeywordsAllTypesProto3Kt.nestedMessage { while_ = 1 }
assertThat(hasDo_()).isTrue()
}
}
@Test
fun testHardKeywordClears() {
hardKeywordsAllTypes {
hardKeywordsAllTypesProto3 {
as_ = 1
clearAs_()
assertThat(hasAs_()).isFalse()
@ -313,11 +338,11 @@ class Proto3Test {
clearIn_()
assertThat(hasIn_()).isFalse()
break_ = HardKeywordsAllTypes.NestedEnum.FOO
break_ = HardKeywordsAllTypesProto3.NestedEnum.FOO
clearBreak_()
assertThat(hasBreak_()).isFalse()
do_ = HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }
do_ = HardKeywordsAllTypesProto3Kt.nestedMessage { while_ = 1 }
clearDo_()
assertThat(hasDo_()).isFalse()
}
@ -326,15 +351,15 @@ class Proto3Test {
@Test
fun testMultipleFiles() {
assertThat(
multipleFilesMessageA {}
com.google.protobuf.kotlin.generator.multipleFilesMessageA {}
).isEqualTo(
MultipleFilesMessageA.newBuilder().build()
com.google.protobuf.kotlin.generator.MultipleFilesMessageA.newBuilder().build()
)
assertThat(
multipleFilesMessageB {}
com.google.protobuf.kotlin.generator.multipleFilesMessageB {}
).isEqualTo(
MultipleFilesMessageB.newBuilder().build()
com.google.protobuf.kotlin.generator.MultipleFilesMessageB.newBuilder().build()
)
}
}

@ -1,8 +1,39 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// LINT: LEGACY_NAMES
syntax = "proto2";
package evil_names_proto2;
package protobuf.kotlin.generator;
option java_package = "evil_names_proto2";
option java_package = "com.google.protobuf.kotlin.generator";
message EvilNamesProto2 {
optional bool initialized = 1;
@ -37,7 +68,7 @@ message EvilNamesProto2 {
optional string by = 25;
}
message HardKeywordsAllTypes {
message HardKeywordsAllTypesProto2 {
message NestedMessage {
optional int32 while = 1;
}

@ -1,8 +1,39 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// LINT: LEGACY_NAMES
syntax = "proto3";
package evil_names_proto3;
package protobuf.kotlin.generator;
option java_package = "evil_names_proto3";
option java_package = "com.google.protobuf.kotlin.generator";
message EvilNamesProto3 {
bool initialized = 1;
@ -50,7 +81,7 @@ message EvilNamesProto3 {
}
}
message HardKeywordsAllTypes {
message HardKeywordsAllTypesProto3 {
message NestedMessage {
optional int32 while = 1;
}

@ -1,8 +1,38 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
package example_extensible_message;
package protobuf.kotlin.test;
option java_package = "example_extensible_message";
option java_package = "com.google.protobuf.kotlin.test";
option java_multiple_files = true;
message ExampleExtensibleMessage {

@ -1,8 +1,38 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package multiple_files_proto3;
package protobuf.kotlin.generator;
option java_package = "multiple_files_proto3";
option java_package = "com.google.protobuf.kotlin.generator";
option java_multiple_files = true;
enum NestedEnum { FOO = 0; }

@ -1295,7 +1295,6 @@ public class JsonFormat {
private static class ParserImpl {
private final com.google.protobuf.TypeRegistry registry;
private final TypeRegistry oldRegistry;
private final JsonParser jsonParser;
private final boolean ignoringUnknownFields;
private final int recursionLimit;
private int currentDepth;
@ -1308,7 +1307,6 @@ public class JsonFormat {
this.registry = registry;
this.oldRegistry = oldRegistry;
this.ignoringUnknownFields = ignoreUnknownFields;
this.jsonParser = new JsonParser();
this.recursionLimit = recursionLimit;
this.currentDepth = 0;
}
@ -1317,7 +1315,7 @@ public class JsonFormat {
try {
JsonReader reader = new JsonReader(json);
reader.setLenient(false);
merge(jsonParser.parse(reader), builder);
merge(JsonParser.parseReader(reader), builder);
} catch (InvalidProtocolBufferException e) {
throw e;
} catch (JsonIOException e) {
@ -1337,7 +1335,7 @@ public class JsonFormat {
try {
JsonReader reader = new JsonReader(new StringReader(json));
reader.setLenient(false);
merge(jsonParser.parse(reader), builder);
merge(JsonParser.parseReader(reader), builder);
} catch (InvalidProtocolBufferException e) {
throw e;
} catch (Exception e) {

@ -0,0 +1,59 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: qrczak@google.com (Marcin Kowalczyk)
#include <google/protobuf/python/python_protobuf.h>
namespace google {
namespace protobuf {
namespace python {
static const Message* GetCProtoInsidePyProtoStub(PyObject* msg) { return NULL; }
static Message* MutableCProtoInsidePyProtoStub(PyObject* msg) { return NULL; }
// This is initialized with a default, stub implementation.
// If python-google.protobuf.cc is loaded, the function pointer is overridden
// with a full implementation.
const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg) =
GetCProtoInsidePyProtoStub;
Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg) =
MutableCProtoInsidePyProtoStub;
const Message* GetCProtoInsidePyProto(PyObject* msg) {
return GetCProtoInsidePyProtoPtr(msg);
}
Message* MutableCProtoInsidePyProto(PyObject* msg) {
return MutableCProtoInsidePyProtoPtr(msg);
}
} // namespace python
} // namespace protobuf
} // namespace google

@ -103,6 +103,15 @@ namespace google {
namespace protobuf {
namespace python {
class MessageReflectionFriend {
public:
static void UnsafeShallowSwapFields(
Message* lhs, Message* rhs,
const std::vector<const FieldDescriptor*>& fields) {
lhs->GetReflection()->UnsafeShallowSwapFields(lhs, rhs, fields);
}
};
static PyObject* kDESCRIPTOR;
PyObject* EnumTypeWrapper_class;
static PyObject* PythonMessage_class;
@ -1280,7 +1289,7 @@ static CMessage* NewCMessage(CMessageClass* type) {
if (self == nullptr) {
return nullptr;
}
self->message = prototype->New();
self->message = prototype->New(nullptr); // Ensures no arena is used.
self->parent = nullptr; // This message owns its data.
return self;
}
@ -1525,7 +1534,7 @@ static int InternalReparentFields(
if (new_message == nullptr) {
return -1;
}
new_message->message = self->message->New();
new_message->message = self->message->New(nullptr);
ScopedPyObjectPtr holder(reinterpret_cast<PyObject*>(new_message));
new_message->child_submessages = new CMessage::SubMessagesMap();
new_message->composite_fields = new CMessage::CompositeFieldsMap();
@ -1555,7 +1564,9 @@ static int InternalReparentFields(
to_release);
}
self->message->GetReflection()->SwapFields(
GOOGLE_CHECK_EQ(self->message->GetArena(), new_message->message->GetArena());
MessageReflectionFriend::UnsafeShallowSwapFields(
self->message, new_message->message,
std::vector<const FieldDescriptor*>(fields_to_swap.begin(),
fields_to_swap.end()));
@ -2689,7 +2700,7 @@ int SetFieldValue(CMessage* self, const FieldDescriptor* field_descriptor,
PyObject* ContainerBase::DeepCopy() {
CMessage* new_parent =
cmessage::NewEmptyMessage(this->parent->GetMessageClass());
new_parent->message = this->parent->message->New();
new_parent->message = this->parent->message->New(nullptr);
// Copy the map field into the new message.
this->parent->message->GetReflection()->SwapFields(

@ -0,0 +1,57 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: qrczak@google.com (Marcin Kowalczyk)
//
// This module exposes the C proto inside the given Python proto, in
// case the Python proto is implemented with a C proto.
#ifndef GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__
#define GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__
#include <Python.h>
namespace google {
namespace protobuf {
class Message;
namespace python {
// Return the pointer to the C proto inside the given Python proto,
// or NULL when this is not a Python proto implemented with a C proto.
const Message* GetCProtoInsidePyProto(PyObject* msg);
Message* MutableCProtoInsidePyProto(PyObject* msg);
} // namespace python
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__

@ -18,7 +18,6 @@ from setuptools import setup, Extension, find_packages
from distutils.command.build_py import build_py as _build_py
from distutils.command.clean import clean as _clean
from distutils.command.build_ext import build_ext as _build_ext
from distutils.spawn import find_executable
# Find the Protocol Compiler.
@ -158,22 +157,6 @@ class build_py(_build_py):
if not any(fnmatch.fnmatchcase(fil, pat=pat) for pat in exclude)]
class build_ext(_build_ext):
def get_ext_filename(self, ext_name):
# since python3.5, python extensions' shared libraries use a suffix that corresponds to the value
# of sysconfig.get_config_var('EXT_SUFFIX') and contains info about the architecture the library targets.
# E.g. on x64 linux the suffix is ".cpython-XYZ-x86_64-linux-gnu.so"
# When crosscompiling python wheels, we need to be able to override this suffix
# so that the resulting file name matches the target architecture and we end up with a well-formed
# wheel.
filename = _build_ext.get_ext_filename(self, ext_name)
orig_ext_suffix = sysconfig.get_config_var("EXT_SUFFIX")
new_ext_suffix = os.getenv("PROTOCOL_BUFFERS_OVERRIDE_EXT_SUFFIX")
if new_ext_suffix and filename.endswith(orig_ext_suffix):
filename = filename[:-len(orig_ext_suffix)] + new_ext_suffix
return filename
class test_conformance(_build_py):
target = 'test_python'
def run(self):
@ -209,18 +192,6 @@ if __name__ == '__main__':
extra_compile_args = []
message_extra_link_args = None
api_implementation_link_args = None
if "darwin" in sys.platform:
if sys.version_info[0] == 2:
message_init_symbol = 'init_message'
api_implementation_init_symbol = 'init_api_implementation'
else:
message_init_symbol = 'PyInit__message'
api_implementation_init_symbol = 'PyInit__api_implementation'
message_extra_link_args = ['-Wl,-exported_symbol,_%s' % message_init_symbol]
api_implementation_link_args = ['-Wl,-exported_symbol,_%s' % api_implementation_init_symbol]
if sys.platform != 'win32':
extra_compile_args.append('-Wno-write-strings')
extra_compile_args.append('-Wno-invalid-offsetof')
@ -271,7 +242,6 @@ if __name__ == '__main__':
include_dirs=[".", "../src"],
libraries=libraries,
extra_objects=extra_objects,
extra_link_args=message_extra_link_args,
library_dirs=['../src/.libs'],
extra_compile_args=extra_compile_args,
),
@ -279,7 +249,6 @@ if __name__ == '__main__':
"google.protobuf.internal._api_implementation",
glob.glob('google/protobuf/internal/api_implementation.cc'),
extra_compile_args=extra_compile_args + ['-DPYTHON_PROTO2_CPP_IMPL_V2'],
extra_link_args=api_implementation_link_args,
),
])
os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp'
@ -322,7 +291,6 @@ if __name__ == '__main__':
cmdclass={
'clean': clean,
'build_py': build_py,
'build_ext': build_ext,
'test_conformance': test_conformance,
},
install_requires=install_requires,

@ -96,11 +96,14 @@ class Any::_Internal {
public:
};
Any::Any(::PROTOBUF_NAMESPACE_ID::Arena* arena)
: ::PROTOBUF_NAMESPACE_ID::Message(arena),
Any::Any(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned)
: ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
_any_metadata_(&type_url_, &value_) {
SharedCtor();
RegisterArenaDtor(arena);
if (!is_message_owned) {
RegisterArenaDtor(arena);
}
// @@protoc_insertion_point(arena_constructor:google.protobuf.Any)
}
Any::Any(const Any& from)
@ -120,18 +123,19 @@ Any::Any(const Any& from)
// @@protoc_insertion_point(copy_constructor:google.protobuf.Any)
}
void Any::SharedCtor() {
inline void Any::SharedCtor() {
type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
}
Any::~Any() {
// @@protoc_insertion_point(destructor:google.protobuf.Any)
if (GetArenaForAllocation() != nullptr) return;
SharedDtor();
_internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}
void Any::SharedDtor() {
inline void Any::SharedDtor() {
GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
@ -265,25 +269,22 @@ size_t Any::ByteSizeLong() const {
return total_size;
}
void Any::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Any)
GOOGLE_DCHECK_NE(&from, this);
const Any* source =
::PROTOBUF_NAMESPACE_ID::DynamicCastToGenerated<Any>(
&from);
if (source == nullptr) {
// @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Any)
::PROTOBUF_NAMESPACE_ID::internal::ReflectionOps::Merge(from, this);
} else {
// @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Any)
MergeFrom(*source);
}
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Any::_class_data_ = {
::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
Any::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Any::GetClassData() const { return &_class_data_; }
void Any::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to,
const ::PROTOBUF_NAMESPACE_ID::Message&from) {
static_cast<Any *>(to)->MergeFrom(
static_cast<const Any &>(from));
}
void Any::MergeFrom(const Any& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Any)
GOOGLE_DCHECK_NE(&from, this);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
(void) cached_has_bits;
@ -293,13 +294,7 @@ void Any::MergeFrom(const Any& from) {
if (!from.value().empty()) {
_internal_set_value(from._internal_value());
}
}
void Any::CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Any)
if (&from == this) return;
Clear();
MergeFrom(from);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}
void Any::CopyFrom(const Any& from) {

@ -170,10 +170,13 @@ class PROTOBUF_EXPORT Any final :
Any* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
return CreateMaybeMessage<Any>(arena);
}
void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
void CopyFrom(const Any& from);
using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
void MergeFrom(const Any& from);
private:
static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from);
public:
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
bool IsInitialized() const final;
@ -193,12 +196,16 @@ class PROTOBUF_EXPORT Any final :
return "google.protobuf.Any";
}
protected:
explicit Any(::PROTOBUF_NAMESPACE_ID::Arena* arena);
explicit Any(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned = false);
private:
static void ArenaDtor(void* object);
inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
public:
static const ClassData _class_data_;
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
// nested types ----------------------------------------------------
@ -215,7 +222,7 @@ class PROTOBUF_EXPORT Any final :
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_type_url(ArgT0&& arg0, ArgT... args);
std::string* mutable_type_url();
PROTOBUF_FUTURE_MUST_USE_RESULT std::string* release_type_url();
PROTOBUF_MUST_USE_RESULT std::string* release_type_url();
void set_allocated_type_url(std::string* type_url);
private:
const std::string& _internal_type_url() const;
@ -229,7 +236,7 @@ class PROTOBUF_EXPORT Any final :
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_value(ArgT0&& arg0, ArgT... args);
std::string* mutable_value();
PROTOBUF_FUTURE_MUST_USE_RESULT std::string* release_value();
PROTOBUF_MUST_USE_RESULT std::string* release_value();
void set_allocated_value(std::string* value);
private:
const std::string& _internal_value() const;
@ -277,8 +284,9 @@ void Any::set_type_url(ArgT0&& arg0, ArgT... args) {
// @@protoc_insertion_point(field_set:google.protobuf.Any.type_url)
}
inline std::string* Any::mutable_type_url() {
std::string* _s = _internal_mutable_type_url();
// @@protoc_insertion_point(field_mutable:google.protobuf.Any.type_url)
return _internal_mutable_type_url();
return _s;
}
inline const std::string& Any::_internal_type_url() const {
return type_url_.Get();
@ -322,8 +330,9 @@ void Any::set_value(ArgT0&& arg0, ArgT... args) {
// @@protoc_insertion_point(field_set:google.protobuf.Any.value)
}
inline std::string* Any::mutable_value() {
std::string* _s = _internal_mutable_value();
// @@protoc_insertion_point(field_mutable:google.protobuf.Any.value)
return _internal_mutable_value();
return _s;
}
inline const std::string& Any::_internal_value() const {
return value_.Get();

@ -178,13 +178,16 @@ void Api::clear_source_context() {
}
source_context_ = nullptr;
}
Api::Api(::PROTOBUF_NAMESPACE_ID::Arena* arena)
: ::PROTOBUF_NAMESPACE_ID::Message(arena),
Api::Api(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned)
: ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
methods_(arena),
options_(arena),
mixins_(arena) {
SharedCtor();
RegisterArenaDtor(arena);
if (!is_message_owned) {
RegisterArenaDtor(arena);
}
// @@protoc_insertion_point(arena_constructor:google.protobuf.Api)
}
Api::Api(const Api& from)
@ -212,7 +215,7 @@ Api::Api(const Api& from)
// @@protoc_insertion_point(copy_constructor:google.protobuf.Api)
}
void Api::SharedCtor() {
inline void Api::SharedCtor() {
name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
version_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
@ -223,11 +226,12 @@ version_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlre
Api::~Api() {
// @@protoc_insertion_point(destructor:google.protobuf.Api)
if (GetArenaForAllocation() != nullptr) return;
SharedDtor();
_internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}
void Api::SharedDtor() {
inline void Api::SharedDtor() {
GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
version_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
@ -499,25 +503,22 @@ size_t Api::ByteSizeLong() const {
return total_size;
}
void Api::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Api)
GOOGLE_DCHECK_NE(&from, this);
const Api* source =
::PROTOBUF_NAMESPACE_ID::DynamicCastToGenerated<Api>(
&from);
if (source == nullptr) {
// @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Api)
::PROTOBUF_NAMESPACE_ID::internal::ReflectionOps::Merge(from, this);
} else {
// @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Api)
MergeFrom(*source);
}
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Api::_class_data_ = {
::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
Api::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Api::GetClassData() const { return &_class_data_; }
void Api::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to,
const ::PROTOBUF_NAMESPACE_ID::Message&from) {
static_cast<Api *>(to)->MergeFrom(
static_cast<const Api &>(from));
}
void Api::MergeFrom(const Api& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Api)
GOOGLE_DCHECK_NE(&from, this);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
(void) cached_has_bits;
@ -536,13 +537,7 @@ void Api::MergeFrom(const Api& from) {
if (from.syntax() != 0) {
_internal_set_syntax(from._internal_syntax());
}
}
void Api::CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Api)
if (&from == this) return;
Clear();
MergeFrom(from);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}
void Api::CopyFrom(const Api& from) {
@ -595,11 +590,14 @@ class Method::_Internal {
void Method::clear_options() {
options_.Clear();
}
Method::Method(::PROTOBUF_NAMESPACE_ID::Arena* arena)
: ::PROTOBUF_NAMESPACE_ID::Message(arena),
Method::Method(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned)
: ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
options_(arena) {
SharedCtor();
RegisterArenaDtor(arena);
if (!is_message_owned) {
RegisterArenaDtor(arena);
}
// @@protoc_insertion_point(arena_constructor:google.protobuf.Method)
}
Method::Method(const Method& from)
@ -627,7 +625,7 @@ Method::Method(const Method& from)
// @@protoc_insertion_point(copy_constructor:google.protobuf.Method)
}
void Method::SharedCtor() {
inline void Method::SharedCtor() {
name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
request_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
response_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
@ -639,11 +637,12 @@ response_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmpty
Method::~Method() {
// @@protoc_insertion_point(destructor:google.protobuf.Method)
if (GetArenaForAllocation() != nullptr) return;
SharedDtor();
_internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}
void Method::SharedDtor() {
inline void Method::SharedDtor() {
GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
request_type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
@ -898,25 +897,22 @@ size_t Method::ByteSizeLong() const {
return total_size;
}
void Method::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Method)
GOOGLE_DCHECK_NE(&from, this);
const Method* source =
::PROTOBUF_NAMESPACE_ID::DynamicCastToGenerated<Method>(
&from);
if (source == nullptr) {
// @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Method)
::PROTOBUF_NAMESPACE_ID::internal::ReflectionOps::Merge(from, this);
} else {
// @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Method)
MergeFrom(*source);
}
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Method::_class_data_ = {
::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
Method::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Method::GetClassData() const { return &_class_data_; }
void Method::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to,
const ::PROTOBUF_NAMESPACE_ID::Message&from) {
static_cast<Method *>(to)->MergeFrom(
static_cast<const Method &>(from));
}
void Method::MergeFrom(const Method& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Method)
GOOGLE_DCHECK_NE(&from, this);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
(void) cached_has_bits;
@ -939,13 +935,7 @@ void Method::MergeFrom(const Method& from) {
if (from.syntax() != 0) {
_internal_set_syntax(from._internal_syntax());
}
}
void Method::CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Method)
if (&from == this) return;
Clear();
MergeFrom(from);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}
void Method::CopyFrom(const Method& from) {
@ -998,10 +988,13 @@ class Mixin::_Internal {
public:
};
Mixin::Mixin(::PROTOBUF_NAMESPACE_ID::Arena* arena)
: ::PROTOBUF_NAMESPACE_ID::Message(arena) {
Mixin::Mixin(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned)
: ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
SharedCtor();
RegisterArenaDtor(arena);
if (!is_message_owned) {
RegisterArenaDtor(arena);
}
// @@protoc_insertion_point(arena_constructor:google.protobuf.Mixin)
}
Mixin::Mixin(const Mixin& from)
@ -1020,18 +1013,19 @@ Mixin::Mixin(const Mixin& from)
// @@protoc_insertion_point(copy_constructor:google.protobuf.Mixin)
}
void Mixin::SharedCtor() {
inline void Mixin::SharedCtor() {
name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
root_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
}
Mixin::~Mixin() {
// @@protoc_insertion_point(destructor:google.protobuf.Mixin)
if (GetArenaForAllocation() != nullptr) return;
SharedDtor();
_internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}
void Mixin::SharedDtor() {
inline void Mixin::SharedDtor() {
GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
root_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
@ -1170,25 +1164,22 @@ size_t Mixin::ByteSizeLong() const {
return total_size;
}
void Mixin::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Mixin)
GOOGLE_DCHECK_NE(&from, this);
const Mixin* source =
::PROTOBUF_NAMESPACE_ID::DynamicCastToGenerated<Mixin>(
&from);
if (source == nullptr) {
// @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Mixin)
::PROTOBUF_NAMESPACE_ID::internal::ReflectionOps::Merge(from, this);
} else {
// @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Mixin)
MergeFrom(*source);
}
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Mixin::_class_data_ = {
::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
Mixin::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Mixin::GetClassData() const { return &_class_data_; }
void Mixin::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to,
const ::PROTOBUF_NAMESPACE_ID::Message&from) {
static_cast<Mixin *>(to)->MergeFrom(
static_cast<const Mixin &>(from));
}
void Mixin::MergeFrom(const Mixin& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Mixin)
GOOGLE_DCHECK_NE(&from, this);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
(void) cached_has_bits;
@ -1198,13 +1189,7 @@ void Mixin::MergeFrom(const Mixin& from) {
if (!from.root().empty()) {
_internal_set_root(from._internal_root());
}
}
void Mixin::CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Mixin)
if (&from == this) return;
Clear();
MergeFrom(from);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}
void Mixin::CopyFrom(const Mixin& from) {

@ -147,10 +147,13 @@ class PROTOBUF_EXPORT Api final :
Api* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
return CreateMaybeMessage<Api>(arena);
}
void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
void CopyFrom(const Api& from);
using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
void MergeFrom(const Api& from);
private:
static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from);
public:
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
bool IsInitialized() const final;
@ -170,12 +173,16 @@ class PROTOBUF_EXPORT Api final :
return "google.protobuf.Api";
}
protected:
explicit Api(::PROTOBUF_NAMESPACE_ID::Arena* arena);
explicit Api(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned = false);
private:
static void ArenaDtor(void* object);
inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
public:
static const ClassData _class_data_;
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
// nested types ----------------------------------------------------
@ -251,7 +258,7 @@ class PROTOBUF_EXPORT Api final :
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_name(ArgT0&& arg0, ArgT... args);
std::string* mutable_name();
PROTOBUF_FUTURE_MUST_USE_RESULT std::string* release_name();
PROTOBUF_MUST_USE_RESULT std::string* release_name();
void set_allocated_name(std::string* name);
private:
const std::string& _internal_name() const;
@ -265,7 +272,7 @@ class PROTOBUF_EXPORT Api final :
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_version(ArgT0&& arg0, ArgT... args);
std::string* mutable_version();
PROTOBUF_FUTURE_MUST_USE_RESULT std::string* release_version();
PROTOBUF_MUST_USE_RESULT std::string* release_version();
void set_allocated_version(std::string* version);
private:
const std::string& _internal_version() const;
@ -280,7 +287,7 @@ class PROTOBUF_EXPORT Api final :
public:
void clear_source_context();
const PROTOBUF_NAMESPACE_ID::SourceContext& source_context() const;
PROTOBUF_FUTURE_MUST_USE_RESULT PROTOBUF_NAMESPACE_ID::SourceContext* release_source_context();
PROTOBUF_MUST_USE_RESULT PROTOBUF_NAMESPACE_ID::SourceContext* release_source_context();
PROTOBUF_NAMESPACE_ID::SourceContext* mutable_source_context();
void set_allocated_source_context(PROTOBUF_NAMESPACE_ID::SourceContext* source_context);
private:
@ -391,10 +398,13 @@ class PROTOBUF_EXPORT Method final :
Method* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
return CreateMaybeMessage<Method>(arena);
}
void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
void CopyFrom(const Method& from);
using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
void MergeFrom(const Method& from);
private:
static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from);
public:
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
bool IsInitialized() const final;
@ -414,12 +424,16 @@ class PROTOBUF_EXPORT Method final :
return "google.protobuf.Method";
}
protected:
explicit Method(::PROTOBUF_NAMESPACE_ID::Arena* arena);
explicit Method(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned = false);
private:
static void ArenaDtor(void* object);
inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
public:
static const ClassData _class_data_;
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
// nested types ----------------------------------------------------
@ -459,7 +473,7 @@ class PROTOBUF_EXPORT Method final :
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_name(ArgT0&& arg0, ArgT... args);
std::string* mutable_name();
PROTOBUF_FUTURE_MUST_USE_RESULT std::string* release_name();
PROTOBUF_MUST_USE_RESULT std::string* release_name();
void set_allocated_name(std::string* name);
private:
const std::string& _internal_name() const;
@ -473,7 +487,7 @@ class PROTOBUF_EXPORT Method final :
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_request_type_url(ArgT0&& arg0, ArgT... args);
std::string* mutable_request_type_url();
PROTOBUF_FUTURE_MUST_USE_RESULT std::string* release_request_type_url();
PROTOBUF_MUST_USE_RESULT std::string* release_request_type_url();
void set_allocated_request_type_url(std::string* request_type_url);
private:
const std::string& _internal_request_type_url() const;
@ -487,7 +501,7 @@ class PROTOBUF_EXPORT Method final :
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_response_type_url(ArgT0&& arg0, ArgT... args);
std::string* mutable_response_type_url();
PROTOBUF_FUTURE_MUST_USE_RESULT std::string* release_response_type_url();
PROTOBUF_MUST_USE_RESULT std::string* release_response_type_url();
void set_allocated_response_type_url(std::string* response_type_url);
private:
const std::string& _internal_response_type_url() const;
@ -613,10 +627,13 @@ class PROTOBUF_EXPORT Mixin final :
Mixin* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
return CreateMaybeMessage<Mixin>(arena);
}
void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
void CopyFrom(const Mixin& from);
using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
void MergeFrom(const Mixin& from);
private:
static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from);
public:
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
bool IsInitialized() const final;
@ -636,12 +653,16 @@ class PROTOBUF_EXPORT Mixin final :
return "google.protobuf.Mixin";
}
protected:
explicit Mixin(::PROTOBUF_NAMESPACE_ID::Arena* arena);
explicit Mixin(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned = false);
private:
static void ArenaDtor(void* object);
inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
public:
static const ClassData _class_data_;
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
// nested types ----------------------------------------------------
@ -658,7 +679,7 @@ class PROTOBUF_EXPORT Mixin final :
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_name(ArgT0&& arg0, ArgT... args);
std::string* mutable_name();
PROTOBUF_FUTURE_MUST_USE_RESULT std::string* release_name();
PROTOBUF_MUST_USE_RESULT std::string* release_name();
void set_allocated_name(std::string* name);
private:
const std::string& _internal_name() const;
@ -672,7 +693,7 @@ class PROTOBUF_EXPORT Mixin final :
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_root(ArgT0&& arg0, ArgT... args);
std::string* mutable_root();
PROTOBUF_FUTURE_MUST_USE_RESULT std::string* release_root();
PROTOBUF_MUST_USE_RESULT std::string* release_root();
void set_allocated_root(std::string* root);
private:
const std::string& _internal_root() const;
@ -719,8 +740,9 @@ void Api::set_name(ArgT0&& arg0, ArgT... args) {
// @@protoc_insertion_point(field_set:google.protobuf.Api.name)
}
inline std::string* Api::mutable_name() {
std::string* _s = _internal_mutable_name();
// @@protoc_insertion_point(field_mutable:google.protobuf.Api.name)
return _internal_mutable_name();
return _s;
}
inline const std::string& Api::_internal_name() const {
return name_.Get();
@ -778,8 +800,9 @@ inline PROTOBUF_NAMESPACE_ID::Method* Api::_internal_add_methods() {
return methods_.Add();
}
inline PROTOBUF_NAMESPACE_ID::Method* Api::add_methods() {
PROTOBUF_NAMESPACE_ID::Method* _add = _internal_add_methods();
// @@protoc_insertion_point(field_add:google.protobuf.Api.methods)
return _internal_add_methods();
return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Method >&
Api::methods() const {
@ -814,8 +837,9 @@ inline PROTOBUF_NAMESPACE_ID::Option* Api::_internal_add_options() {
return options_.Add();
}
inline PROTOBUF_NAMESPACE_ID::Option* Api::add_options() {
PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options();
// @@protoc_insertion_point(field_add:google.protobuf.Api.options)
return _internal_add_options();
return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option >&
Api::options() const {
@ -839,8 +863,9 @@ void Api::set_version(ArgT0&& arg0, ArgT... args) {
// @@protoc_insertion_point(field_set:google.protobuf.Api.version)
}
inline std::string* Api::mutable_version() {
std::string* _s = _internal_mutable_version();
// @@protoc_insertion_point(field_mutable:google.protobuf.Api.version)
return _internal_mutable_version();
return _s;
}
inline const std::string& Api::_internal_version() const {
return version_.Get();
@ -922,8 +947,9 @@ inline PROTOBUF_NAMESPACE_ID::SourceContext* Api::_internal_mutable_source_conte
return source_context_;
}
inline PROTOBUF_NAMESPACE_ID::SourceContext* Api::mutable_source_context() {
PROTOBUF_NAMESPACE_ID::SourceContext* _msg = _internal_mutable_source_context();
// @@protoc_insertion_point(field_mutable:google.protobuf.Api.source_context)
return _internal_mutable_source_context();
return _msg;
}
inline void Api::set_allocated_source_context(PROTOBUF_NAMESPACE_ID::SourceContext* source_context) {
::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
@ -977,8 +1003,9 @@ inline PROTOBUF_NAMESPACE_ID::Mixin* Api::_internal_add_mixins() {
return mixins_.Add();
}
inline PROTOBUF_NAMESPACE_ID::Mixin* Api::add_mixins() {
PROTOBUF_NAMESPACE_ID::Mixin* _add = _internal_add_mixins();
// @@protoc_insertion_point(field_add:google.protobuf.Api.mixins)
return _internal_add_mixins();
return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Mixin >&
Api::mixins() const {
@ -1026,8 +1053,9 @@ void Method::set_name(ArgT0&& arg0, ArgT... args) {
// @@protoc_insertion_point(field_set:google.protobuf.Method.name)
}
inline std::string* Method::mutable_name() {
std::string* _s = _internal_mutable_name();
// @@protoc_insertion_point(field_mutable:google.protobuf.Method.name)
return _internal_mutable_name();
return _s;
}
inline const std::string& Method::_internal_name() const {
return name_.Get();
@ -1071,8 +1099,9 @@ void Method::set_request_type_url(ArgT0&& arg0, ArgT... args) {
// @@protoc_insertion_point(field_set:google.protobuf.Method.request_type_url)
}
inline std::string* Method::mutable_request_type_url() {
std::string* _s = _internal_mutable_request_type_url();
// @@protoc_insertion_point(field_mutable:google.protobuf.Method.request_type_url)
return _internal_mutable_request_type_url();
return _s;
}
inline const std::string& Method::_internal_request_type_url() const {
return request_type_url_.Get();
@ -1136,8 +1165,9 @@ void Method::set_response_type_url(ArgT0&& arg0, ArgT... args) {
// @@protoc_insertion_point(field_set:google.protobuf.Method.response_type_url)
}
inline std::string* Method::mutable_response_type_url() {
std::string* _s = _internal_mutable_response_type_url();
// @@protoc_insertion_point(field_mutable:google.protobuf.Method.response_type_url)
return _internal_mutable_response_type_url();
return _s;
}
inline const std::string& Method::_internal_response_type_url() const {
return response_type_url_.Get();
@ -1212,8 +1242,9 @@ inline PROTOBUF_NAMESPACE_ID::Option* Method::_internal_add_options() {
return options_.Add();
}
inline PROTOBUF_NAMESPACE_ID::Option* Method::add_options() {
PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options();
// @@protoc_insertion_point(field_add:google.protobuf.Method.options)
return _internal_add_options();
return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option >&
Method::options() const {
@ -1261,8 +1292,9 @@ void Mixin::set_name(ArgT0&& arg0, ArgT... args) {
// @@protoc_insertion_point(field_set:google.protobuf.Mixin.name)
}
inline std::string* Mixin::mutable_name() {
std::string* _s = _internal_mutable_name();
// @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.name)
return _internal_mutable_name();
return _s;
}
inline const std::string& Mixin::_internal_name() const {
return name_.Get();
@ -1306,8 +1338,9 @@ void Mixin::set_root(ArgT0&& arg0, ArgT... args) {
// @@protoc_insertion_point(field_set:google.protobuf.Mixin.root)
}
inline std::string* Mixin::mutable_root() {
std::string* _s = _internal_mutable_root();
// @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.root)
return _internal_mutable_root();
return _s;
}
inline const std::string& Mixin::_internal_root() const {
return root_.Get();

@ -84,6 +84,10 @@ void EnableArenaMetrics(ArenaOptions* options);
} // namespace arena_metrics
namespace TestUtil {
class ReflectionTester; // defined in test_util.h
} // namespace TestUtil
namespace internal {
struct ArenaStringPtr; // defined in arenastring.h
@ -405,10 +409,43 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final {
// Provides access to protected GetArenaForAllocation to generated messages.
static Arena* GetArenaForAllocation(const T* p) {
return p->GetArenaForAllocation();
return GetArenaForAllocationInternal(
p, std::is_convertible<T*, MessageLite*>());
}
private:
static Arena* GetArenaForAllocationInternal(
const T* p, std::true_type /*is_derived_from<MessageLite>*/) {
return p->GetArenaForAllocation();
}
static Arena* GetArenaForAllocationInternal(
const T* p, std::false_type /*is_derived_from<MessageLite>*/) {
return GetArenaForAllocationForNonMessage(
p, typename is_arena_constructable::type());
}
static Arena* GetArenaForAllocationForNonMessage(
const T* p, std::true_type /*is_arena_constructible*/) {
return p->GetArena();
}
static Arena* GetArenaForAllocationForNonMessage(
const T* p, std::false_type /*is_arena_constructible*/) {
return GetArenaForAllocationForNonMessageNonArenaConstructible(
p, typename has_get_arena::type());
}
static Arena* GetArenaForAllocationForNonMessageNonArenaConstructible(
const T* p, std::true_type /*has_get_arena*/) {
return p->GetArena();
}
static Arena* GetArenaForAllocationForNonMessageNonArenaConstructible(
const T* p, std::false_type /*has_get_arena*/) {
return nullptr;
}
template <typename U>
static char DestructorSkippable(const typename U::DestructorSkippable_*);
template <typename U>
@ -456,6 +493,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final {
static Arena* GetArena(const T* p) { return p->GetArena(); }
friend class Arena;
friend class TestUtil::ReflectionTester;
};
// Helper typetraits that indicates support for arenas in a type T at compile

@ -622,7 +622,11 @@ TEST(ArenaTest, SetAllocatedAcrossArenas) {
TestAllTypes::NestedMessage* arena2_submessage =
Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
arena2_submessage->set_bb(42);
arena1_message->set_allocated_optional_nested_message(arena2_submessage);
#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT
EXPECT_DEBUG_DEATH(arena1_message->set_allocated_optional_nested_message(
arena2_submessage),
"submessage_arena");
#endif
EXPECT_NE(arena2_submessage,
arena1_message->mutable_optional_nested_message());
}
@ -631,11 +635,43 @@ TEST(ArenaTest, SetAllocatedAcrossArenas) {
Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena1);
arena1_submessage->set_bb(42);
TestAllTypes* heap_message = new TestAllTypes;
heap_message->set_allocated_optional_nested_message(arena1_submessage);
#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT
EXPECT_DEBUG_DEATH(
heap_message->set_allocated_optional_nested_message(arena1_submessage),
"submessage_arena");
#endif
EXPECT_NE(arena1_submessage, heap_message->mutable_optional_nested_message());
delete heap_message;
}
TEST(ArenaTest, UnsafeArenaSetAllocatedAcrossArenas) {
Arena arena1;
TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
{
Arena arena2;
TestAllTypes::NestedMessage* arena2_submessage =
Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
arena2_submessage->set_bb(42);
arena1_message->unsafe_arena_set_allocated_optional_nested_message(
arena2_submessage);
EXPECT_EQ(arena2_submessage,
arena1_message->mutable_optional_nested_message());
EXPECT_EQ(arena2_submessage,
arena1_message->unsafe_arena_release_optional_nested_message());
}
TestAllTypes::NestedMessage* arena1_submessage =
Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena1);
arena1_submessage->set_bb(42);
TestAllTypes* heap_message = new TestAllTypes;
heap_message->unsafe_arena_set_allocated_optional_nested_message(
arena1_submessage);
EXPECT_EQ(arena1_submessage, heap_message->mutable_optional_nested_message());
EXPECT_EQ(arena1_submessage,
heap_message->unsafe_arena_release_optional_nested_message());
delete heap_message;
}
TEST(ArenaTest, SetAllocatedAcrossArenasWithReflection) {
// Same as above, with reflection.
Arena arena1;
@ -655,7 +691,11 @@ TEST(ArenaTest, SetAllocatedAcrossArenasWithReflection) {
TestAllTypes::NestedMessage* arena2_submessage =
Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
arena2_submessage->set_bb(42);
r->SetAllocatedMessage(arena1_message, arena2_submessage, msg_field);
#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT
EXPECT_DEBUG_DEATH(
r->SetAllocatedMessage(arena1_message, arena2_submessage, msg_field),
"GetOwningArena");
#endif
EXPECT_NE(arena2_submessage,
arena1_message->mutable_optional_nested_message());
}
@ -664,11 +704,47 @@ TEST(ArenaTest, SetAllocatedAcrossArenasWithReflection) {
Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena1);
arena1_submessage->set_bb(42);
TestAllTypes* heap_message = new TestAllTypes;
r->SetAllocatedMessage(heap_message, arena1_submessage, msg_field);
#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT
EXPECT_DEBUG_DEATH(
r->SetAllocatedMessage(heap_message, arena1_submessage, msg_field),
"GetOwningArena");
#endif
EXPECT_NE(arena1_submessage, heap_message->mutable_optional_nested_message());
delete heap_message;
}
TEST(ArenaTest, UnsafeArenaSetAllocatedAcrossArenasWithReflection) {
// Same as above, with reflection.
Arena arena1;
TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
const Reflection* r = arena1_message->GetReflection();
const Descriptor* d = arena1_message->GetDescriptor();
const FieldDescriptor* msg_field =
d->FindFieldByName("optional_nested_message");
{
Arena arena2;
TestAllTypes::NestedMessage* arena2_submessage =
Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
arena2_submessage->set_bb(42);
r->UnsafeArenaSetAllocatedMessage(arena1_message, arena2_submessage,
msg_field);
EXPECT_EQ(arena2_submessage,
arena1_message->mutable_optional_nested_message());
EXPECT_EQ(arena2_submessage,
arena1_message->unsafe_arena_release_optional_nested_message());
}
TestAllTypes::NestedMessage* arena1_submessage =
Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena1);
arena1_submessage->set_bb(42);
TestAllTypes* heap_message = new TestAllTypes;
r->UnsafeArenaSetAllocatedMessage(heap_message, arena1_submessage, msg_field);
EXPECT_EQ(arena1_submessage, heap_message->mutable_optional_nested_message());
EXPECT_EQ(arena1_submessage,
heap_message->unsafe_arena_release_optional_nested_message());
delete heap_message;
}
TEST(ArenaTest, AddAllocatedWithReflection) {
Arena arena1;
ArenaMessage* arena1_message = Arena::CreateMessage<ArenaMessage>(&arena1);
@ -727,29 +803,35 @@ TEST(ArenaTest, AddAllocatedToRepeatedField) {
TestAllTypes::NestedMessage* arena2_submessage =
Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
arena2_submessage->set_bb(42);
arena1_message->mutable_repeated_nested_message()->AddAllocated(
arena2_submessage);
// Should copy object.
EXPECT_NE(arena2_submessage, &arena1_message->repeated_nested_message(i));
EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT
EXPECT_DEBUG_DEATH(
arena1_message->mutable_repeated_nested_message()->AddAllocated(
arena2_submessage),
"value_arena");
#endif
// Should not receive object.
EXPECT_TRUE(arena1_message->repeated_nested_message().empty());
}
// Arena->heap case.
TestAllTypes* heap_message = new TestAllTypes();
TestAllTypes* heap_message = new TestAllTypes;
for (int i = 0; i < 10; i++) {
Arena arena2;
TestAllTypes::NestedMessage* arena2_submessage =
Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
arena2_submessage->set_bb(42);
heap_message->mutable_repeated_nested_message()->AddAllocated(
arena2_submessage);
// Should copy object.
EXPECT_NE(arena2_submessage, &heap_message->repeated_nested_message(i));
EXPECT_EQ(42, heap_message->repeated_nested_message(i).bb());
#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT
EXPECT_DEBUG_DEATH(
heap_message->mutable_repeated_nested_message()->AddAllocated(
arena2_submessage),
"value_arena");
#endif
// Should not receive object.
EXPECT_TRUE(heap_message->repeated_nested_message().empty());
}
delete heap_message;
// Heap-arena case for strings (which are not arena-allocated).
// Heap->arena case for strings (which are not arena-allocated).
arena1_message->Clear();
for (int i = 0; i < 10; i++) {
std::string* s = new std::string("Test");
@ -760,6 +842,65 @@ TEST(ArenaTest, AddAllocatedToRepeatedField) {
}
}
TEST(ArenaTest, UnsafeArenaAddAllocatedToRepeatedField) {
// Heap->arena case.
Arena arena1;
TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
{
auto* heap_submessage = new TestAllTypes::NestedMessage;
arena1_message->mutable_repeated_nested_message()->UnsafeArenaAddAllocated(
heap_submessage);
// Should not copy object.
EXPECT_EQ(heap_submessage, &arena1_message->repeated_nested_message(0));
EXPECT_EQ(heap_submessage, arena1_message->mutable_repeated_nested_message()
->UnsafeArenaReleaseLast());
delete heap_submessage;
}
// Arena1->Arena2 case.
arena1_message->Clear();
{
Arena arena2;
TestAllTypes::NestedMessage* arena2_submessage =
Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
arena2_submessage->set_bb(42);
arena1_message->mutable_repeated_nested_message()->UnsafeArenaAddAllocated(
arena2_submessage);
// Should own object.
EXPECT_EQ(arena2_submessage, &arena1_message->repeated_nested_message(0));
EXPECT_EQ(arena2_submessage,
arena1_message->mutable_repeated_nested_message()
->UnsafeArenaReleaseLast());
}
// Arena->heap case.
TestAllTypes* heap_message = new TestAllTypes;
{
Arena arena2;
TestAllTypes::NestedMessage* arena2_submessage =
Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
arena2_submessage->set_bb(42);
heap_message->mutable_repeated_nested_message()->UnsafeArenaAddAllocated(
arena2_submessage);
// Should own object.
EXPECT_EQ(arena2_submessage, &heap_message->repeated_nested_message(0));
EXPECT_EQ(arena2_submessage, heap_message->mutable_repeated_nested_message()
->UnsafeArenaReleaseLast());
}
delete heap_message;
// Heap->arena case for strings (which are not arena-allocated).
arena1_message->Clear();
{
std::string* s = new std::string("Test");
arena1_message->mutable_repeated_string()->UnsafeArenaAddAllocated(s);
// Should not copy.
EXPECT_EQ(s, &arena1_message->repeated_string(0));
EXPECT_EQ("Test", arena1_message->repeated_string(0));
delete arena1_message->mutable_repeated_string()->UnsafeArenaReleaseLast();
}
}
TEST(ArenaTest, AddAllocatedToRepeatedFieldViaReflection) {
// Heap->arena case.
Arena arena1;
@ -784,10 +925,13 @@ TEST(ArenaTest, AddAllocatedToRepeatedFieldViaReflection) {
TestAllTypes::NestedMessage* arena2_submessage =
Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
arena2_submessage->set_bb(42);
r->AddAllocatedMessage(arena1_message, fd, arena2_submessage);
// Should copy object.
EXPECT_NE(arena2_submessage, &arena1_message->repeated_nested_message(i));
EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT
EXPECT_DEBUG_DEATH(
r->AddAllocatedMessage(arena1_message, fd, arena2_submessage),
"value_arena");
#endif
// Should not receive object.
EXPECT_TRUE(arena1_message->repeated_nested_message().empty());
}
// Arena->heap case.
@ -797,10 +941,13 @@ TEST(ArenaTest, AddAllocatedToRepeatedFieldViaReflection) {
TestAllTypes::NestedMessage* arena2_submessage =
Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
arena2_submessage->set_bb(42);
r->AddAllocatedMessage(heap_message, fd, arena2_submessage);
// Should copy object.
EXPECT_NE(arena2_submessage, &heap_message->repeated_nested_message(i));
EXPECT_EQ(42, heap_message->repeated_nested_message(i).bb());
#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT
EXPECT_DEBUG_DEATH(
r->AddAllocatedMessage(heap_message, fd, arena2_submessage),
"value_arena");
#endif
// Should not receive object.
EXPECT_TRUE(heap_message->repeated_nested_message().empty());
}
delete heap_message;
}

@ -54,6 +54,8 @@ namespace internal {
template <typename T>
class ExplicitlyConstructed;
class SwapFieldHelper;
// Lazy string instance to support string fields with non-empty default.
// These are initialized on the first call to .get().
class PROTOBUF_EXPORT LazyString {
@ -241,9 +243,9 @@ struct PROTOBUF_EXPORT ArenaStringPtr {
// Own()'d by any arena. If the field is not set, this returns NULL. The
// caller retains ownership. Clears this field back to NULL state. Used to
// implement release_<field>() methods on generated classes.
PROTOBUF_FUTURE_MUST_USE_RESULT std::string* Release(
PROTOBUF_MUST_USE_RESULT std::string* Release(
const std::string* default_value, ::google::protobuf::Arena* arena);
PROTOBUF_FUTURE_MUST_USE_RESULT std::string* ReleaseNonDefault(
PROTOBUF_MUST_USE_RESULT std::string* ReleaseNonDefault(
const std::string* default_value, ::google::protobuf::Arena* arena);
// Takes a std::string that is heap-allocated, and takes ownership. The
@ -322,6 +324,15 @@ struct PROTOBUF_EXPORT ArenaStringPtr {
bool IsDonatedString() const { return false; }
// Swaps tagged pointer without debug hardening. This is to allow python
// protobuf to maintain pointer stability even in DEBUG builds.
inline PROTOBUF_NDEBUG_INLINE static void UnsafeShallowSwap(
ArenaStringPtr* rhs, ArenaStringPtr* lhs) {
std::swap(lhs->tagged_ptr_, rhs->tagged_ptr_);
}
friend class ::google::protobuf::internal::SwapFieldHelper;
// Slow paths.
// MutableSlow requires that !IsString() || IsDefault
@ -348,8 +359,7 @@ inline PROTOBUF_NDEBUG_INLINE void ArenaStringPtr::InternalSwap( //
(void)default_value;
std::swap(lhs_arena, rhs_arena);
std::swap(lhs->tagged_ptr_, rhs->tagged_ptr_);
#if 0 // TODO(b/186650244): renable this
#ifndef NDEBUG
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
auto force_realloc = [default_value](ArenaStringPtr* p, Arena* arena) {
if (p->IsDefault(default_value)) return;
std::string* old_value = p->tagged_ptr_.Get();
@ -362,8 +372,7 @@ inline PROTOBUF_NDEBUG_INLINE void ArenaStringPtr::InternalSwap( //
};
force_realloc(lhs, lhs_arena);
force_realloc(rhs, rhs_arena);
#endif
#endif
#endif // PROTOBUF_FORCE_COPY_IN_SWAP
}
inline void ArenaStringPtr::ClearNonDefaultToEmpty() {

@ -137,14 +137,10 @@ TEST(BootstrapTest, GeneratedFilesMatch) {
// of the data to compare to.
std::map<std::string, std::string> vpath_map;
std::map<std::string, std::string> rpath_map;
rpath_map
["third_party/protobuf_legacy_opensource/src/google/protobuf/"
"test_messages_proto2"] =
"net/proto2/z_generated_example/test_messages_proto2";
rpath_map
["third_party/protobuf_legacy_opensource/src/google/protobuf/"
"test_messages_proto3"] =
"net/proto2/z_generated_example/test_messages_proto3";
rpath_map["third_party/protobuf/src/google/protobuf/test_messages_proto2"] =
"net/proto2/z_generated_example/test_messages_proto2";
rpath_map["third_party/protobuf/src/google/protobuf/test_messages_proto3"] =
"net/proto2/z_generated_example/test_messages_proto3";
rpath_map["net/proto2/internal/proto2_weak"] =
"net/proto2/z_generated_example/proto2_weak";

@ -93,7 +93,7 @@ void EnumFieldGenerator::GenerateInlineAccessorDefinitions(
" return static_cast< $type$ >($name$_);\n"
"}\n"
"inline $type$ $classname$::$name$() const {\n"
"$annotate_accessor$"
"$annotate_get$"
" // @@protoc_insertion_point(field_get:$full_name$)\n"
" return _internal_$name$();\n"
"}\n"
@ -106,8 +106,8 @@ void EnumFieldGenerator::GenerateInlineAccessorDefinitions(
" $name$_ = value;\n"
"}\n"
"inline void $classname$::set_$name$($type$ value) {\n"
"$annotate_accessor$"
" _internal_set_$name$(value);\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n");
}
@ -183,7 +183,7 @@ void EnumOneofFieldGenerator::GenerateInlineAccessorDefinitions(
" return static_cast< $type$ >($default$);\n"
"}\n"
"inline $type$ $classname$::$name$() const {\n"
"$annotate_accessor$"
"$annotate_get$"
" // @@protoc_insertion_point(field_get:$full_name$)\n"
" return _internal_$name$();\n"
"}\n"
@ -199,9 +199,9 @@ void EnumOneofFieldGenerator::GenerateInlineAccessorDefinitions(
" $field_member$ = value;\n"
"}\n"
"inline void $classname$::set_$name$($type$ value) {\n"
"$annotate_accessor$"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
" _internal_set_$name$(value);\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n");
}
@ -268,17 +268,17 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions(
" return static_cast< $type$ >($name$_.Get(index));\n"
"}\n"
"inline $type$ $classname$::$name$(int index) const {\n"
"$annotate_accessor$"
"$annotate_get$"
" // @@protoc_insertion_point(field_get:$full_name$)\n"
" return _internal_$name$(index);\n"
"}\n"
"inline void $classname$::set_$name$(int index, $type$ value) {\n"
"$annotate_accessor$");
"inline void $classname$::set_$name$(int index, $type$ value) {\n");
if (!HasPreservingUnknownEnumSemantics(descriptor_)) {
format(" assert($type$_IsValid(value));\n");
}
format(
" $name$_.Set(index, value);\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n"
"inline void $classname$::_internal_add_$name$($type$ value) {\n");
@ -289,13 +289,13 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions(
" $name$_.Add(value);\n"
"}\n"
"inline void $classname$::add_$name$($type$ value) {\n"
"$annotate_accessor$"
" // @@protoc_insertion_point(field_add:$full_name$)\n"
" _internal_add_$name$(value);\n"
"$annotate_add$"
" // @@protoc_insertion_point(field_add:$full_name$)\n"
"}\n"
"inline const ::$proto_ns$::RepeatedField<int>&\n"
"$classname$::$name$() const {\n"
"$annotate_accessor$"
"$annotate_list$"
" // @@protoc_insertion_point(field_list:$full_name$)\n"
" return $name$_;\n"
"}\n"
@ -305,7 +305,7 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions(
"}\n"
"inline ::$proto_ns$::RepeatedField<int>*\n"
"$classname$::mutable_$name$() {\n"
"$annotate_accessor$"
"$annotate_mutable_list$"
" // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
" return _internal_mutable_$name$();\n"
"}\n");

@ -36,10 +36,13 @@
#include <cstdint>
#include <memory>
#include <string>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/compiler/cpp/cpp_primitive_field.h>
#include <google/protobuf/compiler/cpp/cpp_string_field.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/cpp/cpp_enum_field.h>
@ -48,7 +51,6 @@
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
namespace google {
namespace protobuf {
@ -57,6 +59,23 @@ namespace cpp {
using internal::WireFormat;
void AddAccessorAnnotations(const FieldDescriptor* descriptor,
const Options& options,
std::map<std::string, std::string>* variables) {
// Can be expanded to include more specific calls, for example, for arena or
// clear calls.
static constexpr const char* kAccessorsAnnotations[] = {
"annotate_add", "annotate_get", "annotate_has",
"annotate_list", "annotate_mutable", "annotate_mutable_list",
"annotate_release", "annotate_set", "annotate_size",
"annotate_clear", "annotate_add_mutable",
};
for (size_t i = 0; i < GOOGLE_ARRAYSIZE(kAccessorsAnnotations); ++i) {
(*variables)[kAccessorsAnnotations[i]] = "";
}
}
void SetCommonFieldVariables(const FieldDescriptor* descriptor,
std::map<std::string, std::string>* variables,
const Options& options) {
@ -81,7 +100,8 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
} else {
(*variables)["set_hasbit_io"] = "";
}
(*variables)["annotate_accessor"] = "";
AddAccessorAnnotations(descriptor, options, variables);
// These variables are placeholders to pick out the beginning and ends of
// identifiers for annotations (when doing so with existing variables would

@ -403,6 +403,11 @@ void FileGenerator::GenerateSourceIncludes(io::Printer* printer) {
IncludeFile("net/proto2/public/wire_format.h", printer);
}
if (HasGeneratedMethods(file_, options_) &&
options_.tctable_mode != Options::kTCTableNever) {
IncludeFile("net/proto2/public/generated_message_tctable_impl.h", printer);
}
if (options_.proto_h) {
// Use the smaller .proto.h files.
for (int i = 0; i < file_->dependency_count(); i++) {
@ -1166,6 +1171,10 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
IncludeFile("net/proto2/public/arena.h", printer);
IncludeFile("net/proto2/public/arenastring.h", printer);
IncludeFile("net/proto2/public/generated_message_table_driven.h", printer);
if (HasGeneratedMethods(file_, options_) &&
options_.tctable_mode != Options::kTCTableNever) {
IncludeFile("net/proto2/public/generated_message_tctable_decl.h", printer);
}
IncludeFile("net/proto2/public/generated_message_util.h", printer);
IncludeFile("net/proto2/public/metadata_lite.h", printer);

@ -245,9 +245,9 @@ void SetCommonVars(const Options& options,
(*variables)["string"] = "std::string";
}
void SetUnknkownFieldsVariable(const Descriptor* descriptor,
const Options& options,
std::map<std::string, std::string>* variables) {
void SetUnknownFieldsVariable(const Descriptor* descriptor,
const Options& options,
std::map<std::string, std::string>* variables) {
std::string proto_ns = ProtobufNamespace(options);
std::string unknown_fields_type;
if (UseUnknownFieldSet(descriptor->file(), options)) {

@ -85,9 +85,9 @@ extern const char kThinSeparator[];
void SetCommonVars(const Options& options,
std::map<std::string, std::string>* variables);
void SetUnknkownFieldsVariable(const Descriptor* descriptor,
const Options& options,
std::map<std::string, std::string>* variables);
void SetUnknownFieldsVariable(const Descriptor* descriptor,
const Options& options,
std::map<std::string, std::string>* variables);
bool GetBootstrapBasename(const Options& options, const std::string& basename,
std::string* bootstrap_basename);
@ -342,7 +342,8 @@ inline bool IsLazy(const FieldDescriptor* field, const Options& options) {
!options.opensource_runtime;
}
inline bool IsFieldUsed(const FieldDescriptor* /* field */, const Options& /* options */) {
inline bool IsFieldUsed(const FieldDescriptor* /* field */,
const Options& options) {
return true;
}
@ -710,7 +711,7 @@ class PROTOC_EXPORT Formatter {
std::vector<int> path;
descriptor->GetLocationPath(&path);
GeneratedCodeInfo::Annotation annotation;
for (int index: path) {
for (int index : path) {
annotation.add_path(index);
}
annotation.set_source_file(descriptor->file()->name());
@ -749,7 +750,8 @@ class PROTOC_EXPORT NamespaceOpener {
if (name_stack_[common_idx] != new_stack_[common_idx]) break;
common_idx++;
}
for (auto it = name_stack_.crbegin(); it != name_stack_.crend() - common_idx; ++it) {
for (auto it = name_stack_.crbegin();
it != name_stack_.crend() - common_idx; ++it) {
if (*it == "PROTOBUF_NAMESPACE_ID") {
printer_->Print("PROTOBUF_NAMESPACE_CLOSE\n");
} else {
@ -864,6 +866,8 @@ inline OneOfRangeImpl OneOfRange(const Descriptor* desc) { return {desc}; }
PROTOC_EXPORT std::string StripProto(const std::string& filename);
inline bool EnableMessageOwnedArena(const Descriptor* desc) { return false; }
} // namespace cpp
} // namespace compiler
} // namespace protobuf

@ -129,7 +129,7 @@ void MapFieldGenerator::GenerateInlineAccessorDefinitions(
"}\n"
"inline const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
"$classname$::$name$() const {\n"
"$annotate_accessor$"
"$annotate_get$"
" // @@protoc_insertion_point(field_map:$full_name$)\n"
" return _internal_$name$();\n"
"}\n"
@ -139,7 +139,7 @@ void MapFieldGenerator::GenerateInlineAccessorDefinitions(
"}\n"
"inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
"$classname$::mutable_$name$() {\n"
"$annotate_accessor$"
"$annotate_mutable$"
" // @@protoc_insertion_point(field_mutable_map:$full_name$)\n"
" return _internal_mutable_$name$();\n"
"}\n");

@ -47,17 +47,18 @@ class MapFieldGenerator : public FieldGenerator {
~MapFieldGenerator();
// implements FieldGenerator ---------------------------------------
void GeneratePrivateMembers(io::Printer* printer) const;
void GenerateAccessorDeclarations(io::Printer* printer) const;
void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
void GenerateClearingCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateSwappingCode(io::Printer* printer) const;
void GenerateConstructorCode(io::Printer* printer) const {}
void GenerateCopyConstructorCode(io::Printer* printer) const;
void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
void GenerateByteSize(io::Printer* printer) const;
void GenerateConstinitInitializer(io::Printer* printer) const;
void GeneratePrivateMembers(io::Printer* printer) const override;
void GenerateAccessorDeclarations(io::Printer* printer) const override;
void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
void GenerateClearingCode(io::Printer* printer) const override;
void GenerateMergingCode(io::Printer* printer) const override;
void GenerateSwappingCode(io::Printer* printer) const override;
void GenerateConstructorCode(io::Printer* printer) const override {}
void GenerateCopyConstructorCode(io::Printer* printer) const override;
void GenerateSerializeWithCachedSizesToArray(
io::Printer* printer) const override;
void GenerateByteSize(io::Printer* printer) const override;
void GenerateConstinitInitializer(io::Printer* printer) const override;
bool GenerateArenaDestructorCode(io::Printer* printer) const override;
private:

@ -61,6 +61,9 @@
#include <google/protobuf/stubs/hash.h>
// Must be included last.
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace compiler {
@ -571,7 +574,12 @@ MessageGenerator::MessageGenerator(
variables_["classtype"] = QualifiedClassName(descriptor_, options);
variables_["full_name"] = descriptor_->full_name();
variables_["superclass"] = SuperClassName(descriptor_, options_);
SetUnknkownFieldsVariable(descriptor_, options_, &variables_);
variables_["annotate_serialize"] = "";
variables_["annotate_deserialize"] = "";
variables_["annotate_reflection"] = "";
variables_["annotate_bytesize"] = "";
SetUnknownFieldsVariable(descriptor_, options_, &variables_);
// Compute optimized field order to be used for layout and initialization
// purposes.
@ -612,7 +620,8 @@ MessageGenerator::MessageGenerator(
table_driven_ = TableDrivenParsingEnabled(descriptor_, options_);
parse_function_generator_.reset(new ParseFunctionGenerator(
descriptor_, max_has_bit_index_, options_, scc_analyzer_));
descriptor_, max_has_bit_index_, has_bit_indices_, options_,
scc_analyzer_, variables_));
}
MessageGenerator::~MessageGenerator() = default;
@ -767,7 +776,7 @@ void MessageGenerator::GenerateSingularFieldHasBits(
if (field->options().weak()) {
format(
"inline bool $classname$::has_$name$() const {\n"
"$annotate_accessor$"
"$annotate_has$"
" return _weak_field_map_.Has($number$);\n"
"}\n");
return;
@ -796,7 +805,7 @@ void MessageGenerator::GenerateSingularFieldHasBits(
" return value;\n"
"}\n"
"inline bool $classname$::has_$name$() const {\n"
"$annotate_accessor$"
"$annotate_has$"
" return _internal_has_$name$();\n"
"}\n");
} else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
@ -815,7 +824,7 @@ void MessageGenerator::GenerateSingularFieldHasBits(
}
format(
"inline bool $classname$::has_$name$() const {\n"
"$annotate_accessor$"
"$annotate_has$"
" return _internal_has_$name$();\n"
"}\n");
}
@ -865,7 +874,7 @@ void MessageGenerator::GenerateOneofMemberHasBits(const FieldDescriptor* field,
" return $oneof_name$_case() == k$field_name$;\n"
"}\n"
"inline bool $classname$::has_$name$() const {\n"
"$annotate_accessor$"
"$annotate_has$"
" return _internal_has_$name$();\n"
"}\n");
} else if (HasPrivateHasMethod(field)) {
@ -893,9 +902,7 @@ void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field,
if (is_inline) {
format("inline ");
}
format(
"void $classname$::clear_$name$() {\n"
"$annotate_accessor$");
format("void $classname$::clear_$name$() {\n");
format.Indent();
@ -918,7 +925,7 @@ void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field,
format("_has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n");
}
}
format("$annotate_clear$");
format.Outdent();
format("}\n");
}
@ -952,7 +959,7 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) {
" return $name$_$1$.size();\n"
"}\n"
"inline int $classname$::$name$_size() const {\n"
"$annotate_accessor$"
"$annotate_size$"
" return _internal_$name$_size();\n"
"}\n",
IsImplicitWeakField(field, options_, scc_analyzer_) &&
@ -1079,7 +1086,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
}
if (HasDescriptorMethods(descriptor_->file(), options_)) {
format(
" void MergeFrom(const ::$proto_ns$::Message& other) final;\n"
" using ::$proto_ns$::Message::MergeFrom;\n"
""
" ::$proto_ns$::Metadata GetMetadata() const final;\n");
}
format("};\n");
@ -1094,8 +1102,14 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
format(" public:\n");
format.Indent();
if (EnableMessageOwnedArena(descriptor_)) {
format(
"inline $classname$() : $classname$("
"new ::$proto_ns$::Arena(), true) {}\n");
} else {
format("inline $classname$() : $classname$(nullptr) {}\n");
}
format(
"inline $classname$() : $classname$(nullptr) {}\n"
"~$classname$() override;\n"
"explicit constexpr "
"$classname$(::$proto_ns$::internal::ConstantInitialized);\n"
@ -1163,6 +1177,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
" return default_instance().GetMetadata().descriptor;\n"
"}\n"
"static const ::$proto_ns$::Reflection* GetReflection() {\n"
"$annotate_reflection$"
" return default_instance().GetMetadata().reflection;\n"
"}\n");
}
@ -1274,7 +1289,12 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
"}\n"
"inline void Swap($classname$* other) {\n"
" if (other == this) return;\n"
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
" if (GetOwningArena() != nullptr &&\n"
" GetOwningArena() == other->GetOwningArena()) {\n"
#else // PROTOBUF_FORCE_COPY_IN_SWAP
" if (GetOwningArena() == other->GetOwningArena()) {\n"
#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
" InternalSwap(other);\n"
" } else {\n"
" ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);\n"
@ -1307,20 +1327,33 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
if (HasGeneratedMethods(descriptor_->file(), options_)) {
if (HasDescriptorMethods(descriptor_->file(), options_)) {
format(
"void CopyFrom(const ::$proto_ns$::Message& from) final;\n"
"void MergeFrom(const ::$proto_ns$::Message& from) final;\n");
// Use Message's built-in MergeFrom and CopyFrom when the passed-in
// argument is a generic Message instance, and only define the custom
// MergeFrom and CopyFrom instances when the source of the merge/copy
// is known to be the same class as the destination.
// TODO(jorg): Define MergeFrom in terms of MergeImpl, rather than the
// other way around, to save even more code size.
"using $superclass$::CopyFrom;\n"
"void CopyFrom(const $classname$& from);\n"
""
"using $superclass$::MergeFrom;\n"
"void MergeFrom(const $classname$& from);\n"
"private:\n"
"static void MergeImpl(::$proto_ns$::Message*to, const "
"::$proto_ns$::Message&from);\n"
"public:\n");
} else {
format(
"void CheckTypeAndMergeFrom(const ::$proto_ns$::MessageLite& from)\n"
" final;\n");
"void CheckTypeAndMergeFrom(const ::$proto_ns$::MessageLite& from)"
" final;\n"
"void CopyFrom(const $classname$& from);\n"
"void MergeFrom(const $classname$& from);\n");
}
format.Set("clear_final",
ShouldMarkClearAsFinal(descriptor_, options_) ? "final" : "");
format(
"void CopyFrom(const $classname$& from);\n"
"void MergeFrom(const $classname$& from);\n"
"PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear()$ clear_final$;\n"
"bool IsInitialized() const final;\n"
"\n"
@ -1362,7 +1395,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
// protos to give access to this constructor, breaking the invariants
// we rely on.
"protected:\n"
"explicit $classname$(::$proto_ns$::Arena* arena);\n"
"explicit $classname$(::$proto_ns$::Arena* arena,\n"
" bool is_message_owned = false);\n"
"private:\n"
"static void ArenaDtor(void* object);\n"
"inline void RegisterArenaDtor(::$proto_ns$::Arena* arena);\n");
@ -1372,6 +1406,13 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
"\n");
if (HasDescriptorMethods(descriptor_->file(), options_)) {
if (HasGeneratedMethods(descriptor_->file(), options_)) {
format(
"static const ClassData _class_data_;\n"
"const ::$proto_ns$::Message::ClassData*"
"GetClassData() const final;\n"
"\n");
}
format(
"::$proto_ns$::Metadata GetMetadata() const final;\n"
"\n");
@ -1454,6 +1495,10 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
"size_t RequiredFieldsByteSizeFallback() const;\n\n");
}
if (HasGeneratedMethods(descriptor_->file(), options_)) {
parse_function_generator_->GenerateDataDecls(printer);
}
// Prepare decls for _cached_size_ and _has_bits_. Their position in the
// output will be determined later.
@ -1882,12 +1927,6 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
" $file_level_metadata$[$1$]);\n"
"}\n",
index_in_file_messages_);
format(
"void $classname$::MergeFrom(\n"
" const ::$proto_ns$::Message& other) {\n"
" ::$proto_ns$::Message::MergeFrom(other);\n"
"}\n"
"\n");
}
return;
}
@ -1987,6 +2026,8 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
parse_function_generator_->GenerateMethodImpls(printer);
format("\n");
parse_function_generator_->GenerateDataDefinitions(printer);
GenerateSerializeWithCachedSizesToArray(printer);
format("\n");
@ -2302,7 +2343,7 @@ std::pair<size_t, size_t> MessageGenerator::GenerateOffsets(
void MessageGenerator::GenerateSharedConstructorCode(io::Printer* printer) {
Formatter format(printer, variables_);
format("void $classname$::SharedCtor() {\n");
format("inline void $classname$::SharedCtor() {\n");
std::vector<bool> processed(optimized_order_.size(), false);
GenerateConstructorBody(printer, processed, false);
@ -2317,7 +2358,7 @@ void MessageGenerator::GenerateSharedConstructorCode(io::Printer* printer) {
void MessageGenerator::GenerateSharedDestructorCode(io::Printer* printer) {
Formatter format(printer, variables_);
format("void $classname$::SharedDtor() {\n");
format("inline void $classname$::SharedDtor() {\n");
format.Indent();
format("$DCHK$(GetArenaForAllocation() == nullptr);\n");
// Write the destructors for each field except oneof members.
@ -2502,7 +2543,7 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) {
std::string superclass;
superclass = SuperClassName(descriptor_, options_);
std::string initializer_with_arena = superclass + "(arena)";
std::string initializer_with_arena = superclass + "(arena, is_message_owned)";
if (descriptor_->extension_range_count() > 0) {
initializer_with_arena += ",\n _extensions_(arena)";
@ -2538,16 +2579,19 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) {
}
format(
"$classname$::$classname$(::$proto_ns$::Arena* arena)\n"
"$classname$::$classname$(::$proto_ns$::Arena* arena,\n"
" bool is_message_owned)\n"
" : $1$ {\n"
" SharedCtor();\n"
" RegisterArenaDtor(arena);\n"
" if (!is_message_owned) {\n"
" RegisterArenaDtor(arena);\n"
" }\n"
" // @@protoc_insertion_point(arena_constructor:$full_name$)\n"
"}\n",
initializer_with_arena);
std::map<std::string, std::string> vars;
SetUnknkownFieldsVariable(descriptor_, options_, &vars);
SetUnknownFieldsVariable(descriptor_, options_, &vars);
format.AddMap(vars);
// Generate the copy constructor.
@ -2646,6 +2690,7 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) {
format(
"$classname$::~$classname$() {\n"
" // @@protoc_insertion_point(destructor:$full_name$)\n"
" if (GetArenaForAllocation() != nullptr) return;\n"
" SharedDtor();\n"
" _internal_metadata_.Delete<$unknown_fields_type$>();\n"
"}\n"
@ -2838,7 +2883,7 @@ void MessageGenerator::GenerateClear(io::Printer* printer) {
}
std::map<std::string, std::string> vars;
SetUnknkownFieldsVariable(descriptor_, options_, &vars);
SetUnknownFieldsVariable(descriptor_, options_, &vars);
format.AddMap(vars);
format("_internal_metadata_.Clear<$unknown_fields_type$>();\n");
@ -2903,7 +2948,7 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) {
}
std::map<std::string, std::string> vars;
SetUnknkownFieldsVariable(descriptor_, options_, &vars);
SetUnknownFieldsVariable(descriptor_, options_, &vars);
format.AddMap(vars);
format("_internal_metadata_.InternalSwap(&other->_internal_metadata_);\n");
@ -2973,35 +3018,30 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) {
void MessageGenerator::GenerateMergeFrom(io::Printer* printer) {
Formatter format(printer, variables_);
if (HasDescriptorMethods(descriptor_->file(), options_)) {
// Generate the generalized MergeFrom (aka that which takes in the Message
// base class as a parameter).
format(
"void $classname$::MergeFrom(const ::$proto_ns$::Message& from) {\n"
"// @@protoc_insertion_point(generalized_merge_from_start:"
"$full_name$)\n"
" $DCHK$_NE(&from, this);\n");
format.Indent();
// We don't override the generalized MergeFrom (aka that which
// takes in the Message base class as a parameter); instead we just
// let the base Message::MergeFrom take care of it. The base MergeFrom
// knows how to quickly confirm the types exactly match, and if so, will
// use GetClassData() to retrieve the address of MergeImpl, which calls
// the fast MergeFrom overload. Most callers avoid all this by passing
// a "from" message that is the same type as the message being merged
// into, rather than a generic Message.
// Cast the message to the proper type. If we find that the message is
// *not* of the proper type, we can still call Merge via the reflection
// system, as the GOOGLE_CHECK above ensured that we have the same descriptor
// for each message.
format(
"const $classname$* source =\n"
" ::$proto_ns$::DynamicCastToGenerated<$classname$>(\n"
" &from);\n"
"if (source == nullptr) {\n"
"// @@protoc_insertion_point(generalized_merge_from_cast_fail:"
"$full_name$)\n"
" ::$proto_ns$::internal::ReflectionOps::Merge(from, this);\n"
"} else {\n"
"// @@protoc_insertion_point(generalized_merge_from_cast_success:"
"$full_name$)\n"
" MergeFrom(*source);\n"
"}\n");
format.Outdent();
format("}\n");
format(
"const ::$proto_ns$::Message::ClassData "
"$classname$::_class_data_ = {\n"
" ::$proto_ns$::Message::CopyWithSizeCheck,\n"
" $classname$::MergeImpl\n"
"};\n"
"const ::$proto_ns$::Message::ClassData*"
"$classname$::GetClassData() const { return &_class_data_; }\n"
"\n"
"void $classname$::MergeImpl(::$proto_ns$::Message*to,\n"
" const ::$proto_ns$::Message&from) {\n"
" static_cast<$classname$ *>(to)->MergeFrom(\n"
" static_cast<const $classname$ &>(from));\n"
"}\n"
"\n");
} else {
// Generate CheckTypeAndMergeFrom().
format(
@ -3023,15 +3063,7 @@ void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) {
" $DCHK$_NE(&from, this);\n");
format.Indent();
if (descriptor_->extension_range_count() > 0) {
format("_extensions_.MergeFrom(from._extensions_);\n");
}
std::map<std::string, std::string> vars;
SetUnknkownFieldsVariable(descriptor_, options_, &vars);
format.AddMap(vars);
format(
"_internal_metadata_.MergeFrom<$unknown_fields_type$>(from._internal_"
"metadata_);\n"
"$uint32$ cached_has_bits = 0;\n"
"(void) cached_has_bits;\n\n");
@ -3169,6 +3201,16 @@ void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) {
format("_weak_field_map_.MergeFrom(from._weak_field_map_);\n");
}
// Merging of extensions and unknown fields is done last, to maximize
// the opportunity for tail calls.
if (descriptor_->extension_range_count() > 0) {
format("_extensions_.MergeFrom(from._extensions_);\n");
}
format(
"_internal_metadata_.MergeFrom<$unknown_fields_type$>(from._internal_"
"metadata_);\n");
format.Outdent();
format("}\n");
}
@ -3176,38 +3218,16 @@ void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) {
void MessageGenerator::GenerateCopyFrom(io::Printer* printer) {
Formatter format(printer, variables_);
if (HasDescriptorMethods(descriptor_->file(), options_)) {
// Generate the generalized CopyFrom (aka that which takes in the Message
// base class as a parameter).
format(
"void $classname$::CopyFrom(const ::$proto_ns$::Message& from) {\n"
"// @@protoc_insertion_point(generalized_copy_from_start:"
"$full_name$)\n");
format.Indent();
format("if (&from == this) return;\n");
if (!options_.opensource_runtime) {
// This check is disabled in the opensource release because we're
// concerned that many users do not define NDEBUG in their release
// builds.
format(
"#ifndef NDEBUG\n"
"size_t from_size = from.ByteSizeLong();\n"
"#endif\n"
"Clear();\n"
"#ifndef NDEBUG\n"
"$CHK$_EQ(from_size, from.ByteSizeLong())\n"
" << \"Source of CopyFrom changed when clearing target. Either \"\n"
" << \"source is a nested message in target (not allowed), or \"\n"
" << \"another thread is modifying the source.\";\n"
"#endif\n");
} else {
format("Clear();\n");
}
format("MergeFrom(from);\n");
format.Outdent();
format("}\n\n");
// We don't override the generalized CopyFrom (aka that which
// takes in the Message base class as a parameter); instead we just
// let the base Message::CopyFrom take care of it. The base MergeFrom
// knows how to quickly confirm the types exactly match, and if so, will
// use GetClassData() to get the address of Message::CopyWithSizeCheck,
// which calls Clear() and then MergeFrom(), as well as making sure that
// clearing the destination message doesn't alter the size of the source,
// when in debug builds.
// Most callers avoid this by passing a "from" message that is the same
// type as the message being merged into, rather than a generic Message.
}
// Generate the class-specific CopyFrom.
@ -3230,8 +3250,8 @@ void MessageGenerator::GenerateCopyFrom(io::Printer* printer) {
"#ifndef NDEBUG\n"
"$CHK$_EQ(from_size, from.ByteSizeLong())\n"
" << \"Source of CopyFrom changed when clearing target. Either \"\n"
" << \"source is a nested message in target (not allowed), or \"\n"
" << \"another thread is modifying the source.\";\n"
" \"source is a nested message in target (not allowed), or \"\n"
" \"another thread is modifying the source.\";\n"
"#endif\n");
} else {
format("Clear();\n");
@ -3329,10 +3349,11 @@ void MessageGenerator::GenerateSerializeWithCachedSizesToArray(
"$uint8$* $classname$::_InternalSerialize(\n"
" $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) "
"const {\n"
"$annotate_serialize$"
" target = _extensions_."
"InternalSerializeMessageSetWithCachedSizesToArray(target, stream);\n");
std::map<std::string, std::string> vars;
SetUnknkownFieldsVariable(descriptor_, options_, &vars);
SetUnknownFieldsVariable(descriptor_, options_, &vars);
format.AddMap(vars);
format(
" target = ::$proto_ns$::internal::"
@ -3347,7 +3368,8 @@ void MessageGenerator::GenerateSerializeWithCachedSizesToArray(
format(
"$uint8$* $classname$::_InternalSerialize(\n"
" $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) "
"const {\n");
"const {\n"
"$annotate_serialize$");
format.Indent();
format("// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n");
@ -3570,7 +3592,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody(
}
std::map<std::string, std::string> vars;
SetUnknkownFieldsVariable(descriptor_, options_, &vars);
SetUnknownFieldsVariable(descriptor_, options_, &vars);
format.AddMap(vars);
format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n");
format.Indent();
@ -3662,7 +3684,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled(
format("}\n");
std::map<std::string, std::string> vars;
SetUnknkownFieldsVariable(descriptor_, options_, &vars);
SetUnknownFieldsVariable(descriptor_, options_, &vars);
format.AddMap(vars);
format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n");
format.Indent();
@ -3703,10 +3725,11 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) {
if (descriptor_->options().message_set_wire_format()) {
// Special-case MessageSet.
std::map<std::string, std::string> vars;
SetUnknkownFieldsVariable(descriptor_, options_, &vars);
SetUnknownFieldsVariable(descriptor_, options_, &vars);
format.AddMap(vars);
format(
"size_t $classname$::ByteSizeLong() const {\n"
"$annotate_bytesize$"
"// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n"
" size_t total_size = _extensions_.MessageSetByteSize();\n"
" if ($have_unknown_fields$) {\n"
@ -3752,6 +3775,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) {
format(
"size_t $classname$::ByteSizeLong() const {\n"
"$annotate_bytesize$"
"// @@protoc_insertion_point(message_byte_size_start:$full_name$)\n");
format.Indent();
format(
@ -3765,7 +3789,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) {
}
std::map<std::string, std::string> vars;
SetUnknkownFieldsVariable(descriptor_, options_, &vars);
SetUnknownFieldsVariable(descriptor_, options_, &vars);
format.AddMap(vars);
// Handle required fields (if any). We expect all of them to be
@ -4070,3 +4094,5 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
} // namespace compiler
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>

@ -109,7 +109,7 @@ void MessageFieldGenerator::GenerateAccessorDeclarations(
format(
"$deprecated_attr$const $type$& ${1$$name$$}$() const { "
"__builtin_trap(); }\n"
"PROTOBUF_FUTURE_MUST_USE_RESULT $deprecated_attr$$type$* "
"PROTOBUF_MUST_USE_RESULT $deprecated_attr$$type$* "
"${1$$release_name$$}$() { "
"__builtin_trap(); }\n"
"$deprecated_attr$$type$* ${1$mutable_$name$$}$() { "
@ -126,7 +126,7 @@ void MessageFieldGenerator::GenerateAccessorDeclarations(
}
format(
"$deprecated_attr$const $type$& ${1$$name$$}$() const;\n"
"PROTOBUF_FUTURE_MUST_USE_RESULT $deprecated_attr$$type$* "
"PROTOBUF_MUST_USE_RESULT $deprecated_attr$$type$* "
"${1$$release_name$$}$();\n"
"$deprecated_attr$$type$* ${1$mutable_$name$$}$();\n"
"$deprecated_attr$void ${1$set_allocated_$name$$}$"
@ -163,7 +163,7 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
" $type_default_instance$);\n"
"}\n"
"inline const $type$& $classname$::$name$() const {\n"
"$annotate_accessor$"
"$annotate_get$"
" // @@protoc_insertion_point(field_get:$full_name$)\n"
" return _internal_$name$();\n"
"}\n");
@ -171,7 +171,6 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
format(
"inline void $classname$::unsafe_arena_set_allocated_$name$(\n"
" $type$* $name$) {\n"
"$annotate_accessor$"
// If we're not on an arena, free whatever we were holding before.
// (If we are on arena, we can just forget the earlier pointer.)
" if (GetArenaForAllocation() == nullptr) {\n"
@ -190,12 +189,14 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
" } else {\n"
" $clear_hasbit$\n"
" }\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_unsafe_arena_set_allocated"
":$full_name$)\n"
"}\n");
format(
"inline $type$* $classname$::$release_name$() {\n"
"$type_reference_function$"
"$annotate_release$"
" $clear_hasbit$\n"
" $type$* temp = $casted_member$;\n"
" $name$_ = nullptr;\n"
@ -205,7 +206,7 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
" return temp;\n"
"}\n"
"inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
"$annotate_accessor$"
"$annotate_release$"
" // @@protoc_insertion_point(field_release:$full_name$)\n"
"$type_reference_function$"
" $clear_hasbit$\n"
@ -230,16 +231,16 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
" return $casted_member$;\n"
"}\n"
"inline $type$* $classname$::mutable_$name$() {\n"
"$annotate_accessor$"
" $type$* _msg = _internal_mutable_$name$();\n"
"$annotate_mutable$"
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
" return _internal_mutable_$name$();\n"
" return _msg;\n"
"}\n");
// We handle the most common case inline, and delegate less common cases to
// the slow fallback function.
format(
"inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
"$annotate_accessor$"
" ::$proto_ns$::Arena* message_arena = GetArenaForAllocation();\n");
format(" if (message_arena == nullptr) {\n");
if (IsCrossFileMessage(descriptor_)) {
@ -281,6 +282,7 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
format(" $name$_ = $name$;\n");
}
format(
"$annotate_set$"
" // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
"}\n");
}
@ -494,7 +496,6 @@ void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions(
Formatter format(printer, variables_);
format(
"void $classname$::set_allocated_$name$($type$* $name$) {\n"
"$annotate_accessor$"
" ::$proto_ns$::Arena* message_arena = GetArenaForAllocation();\n"
" clear_$oneof_name$();\n"
" if ($name$) {\n");
@ -521,6 +522,7 @@ void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions(
" set_has_$name$();\n"
" $field_member$ = $name$;\n"
" }\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
"}\n");
}
@ -530,7 +532,7 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions(
Formatter format(printer, variables_);
format(
"inline $type$* $classname$::$release_name$() {\n"
"$annotate_accessor$"
"$annotate_release$"
" // @@protoc_insertion_point(field_release:$full_name$)\n"
" if (_internal_has_$name$()) {\n"
" clear_has_$oneof_name$();\n"
@ -552,12 +554,12 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions(
" : reinterpret_cast< $type$&>($type_default_instance$);\n"
"}\n"
"inline const $type$& $classname$::$name$() const {\n"
"$annotate_accessor$"
"$annotate_get$"
" // @@protoc_insertion_point(field_get:$full_name$)\n"
" return _internal_$name$();\n"
"}\n"
"inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
"$annotate_accessor$"
"$annotate_release$"
" // @@protoc_insertion_point(field_unsafe_arena_release"
":$full_name$)\n"
" if (_internal_has_$name$()) {\n"
@ -571,7 +573,6 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions(
"}\n"
"inline void $classname$::unsafe_arena_set_allocated_$name$"
"($type$* $name$) {\n"
"$annotate_accessor$"
// We rely on the oneof clear method to free the earlier contents of
// this oneof. We can directly use the pointer we're given to set the
// new value.
@ -580,6 +581,7 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions(
" set_has_$name$();\n"
" $field_member$ = $name$;\n"
" }\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
"$full_name$)\n"
"}\n"
@ -593,9 +595,10 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions(
" return $field_member$;\n"
"}\n"
"inline $type$* $classname$::mutable_$name$() {\n"
"$annotate_accessor$"
" $type$* _msg = _internal_mutable_$name$();\n"
"$annotate_mutable$"
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
" return _internal_mutable_$name$();\n"
" return _msg;\n"
"}\n");
}
@ -701,7 +704,7 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions(
format(
"inline $type$* $classname$::mutable_$name$(int index) {\n"
"$annotate_accessor$"
"$annotate_mutable$"
// TODO(dlj): move insertion points
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
"$type_reference_function$"
@ -709,7 +712,7 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions(
"}\n"
"inline ::$proto_ns$::RepeatedPtrField< $type$ >*\n"
"$classname$::mutable_$name$() {\n"
"$annotate_accessor$"
"$annotate_mutable_list$"
" // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
"$type_reference_function$"
" return &$name$_$weak$;\n"
@ -733,7 +736,7 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions(
format(
"inline const $type$& $classname$::$name$(int index) const {\n"
"$annotate_accessor$"
"$annotate_get$"
" // @@protoc_insertion_point(field_get:$full_name$)\n"
" return _internal_$name$(index);\n"
"}\n"
@ -741,15 +744,16 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions(
" return $name$_$weak$.Add();\n"
"}\n"
"inline $type$* $classname$::add_$name$() {\n"
"$annotate_accessor$"
" $type$* _add = _internal_add_$name$();\n"
"$annotate_add_mutable$"
" // @@protoc_insertion_point(field_add:$full_name$)\n"
" return _internal_add_$name$();\n"
" return _add;\n"
"}\n");
format(
"inline const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
"$classname$::$name$() const {\n"
"$annotate_accessor$"
"$annotate_list$"
" // @@protoc_insertion_point(field_list:$full_name$)\n"
"$type_reference_function$"
" return $name$_$weak$;\n"

@ -74,6 +74,7 @@ struct Options {
kTCTableGuarded,
kTCTableAlways
} tctable_mode = kTCTableNever;
bool inject_field_listener_events = false;
};
} // namespace cpp

@ -30,6 +30,9 @@
#include <google/protobuf/compiler/cpp/cpp_parse_function_generator.h>
#include <limits>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/wire_format.h>
namespace google {
@ -38,6 +41,7 @@ namespace compiler {
namespace cpp {
namespace {
using google::protobuf::internal::TcFieldData;
using google::protobuf::internal::WireFormat;
using google::protobuf::internal::WireFormatLite;
@ -60,58 +64,222 @@ bool HasInternalAccessors(const FieldOptions::CType ctype) {
return ctype == FieldOptions::STRING || ctype == FieldOptions::CORD;
}
bool IsTCTableEnabled(const Options& options) {
bool IsTcTableEnabled(const Options& options) {
return options.tctable_mode == Options::kTCTableAlways;
}
bool IsTCTableGuarded(const Options& options) {
bool IsTcTableGuarded(const Options& options) {
return options.tctable_mode == Options::kTCTableGuarded;
}
bool IsTCTableDisabled(const Options& options) {
bool IsTcTableDisabled(const Options& options) {
return options.tctable_mode == Options::kTCTableNever;
}
int TagSize(uint32_t field_number) {
if (field_number < 16) return 1;
GOOGLE_CHECK_LT(field_number, (1 << 14))
<< "coded tag for " << field_number << " too big for uint16_t";
return 2;
}
const char* TagType(const FieldDescriptor* field) {
return CodedTagType(TagSize(field->number()));
}
std::string MessageParseFunctionName(const FieldDescriptor* field,
const Options& options) {
std::string name =
"::" + ProtobufNamespace(options) + "::internal::TcParserBase::";
if (field->is_repeated()) {
name.append("Repeated");
} else {
name.append("Singular");
}
name.append("ParseMessage<" + ClassName(field->message_type()) + ", " +
TagType(field) + ">");
return name;
}
std::string FieldParseFunctionName(const FieldDescriptor* field,
const Options& options,
uint32_t table_size_log2);
} // namespace
ParseFunctionGenerator::ParseFunctionGenerator(const Descriptor* descriptor,
int num_hasbits,
const Options& options,
MessageSCCAnalyzer* scc_analyzer)
const char* CodedTagType(int tag_size) {
return tag_size == 1 ? "uint8_t" : "uint16_t";
}
TailCallTableInfo::TailCallTableInfo(const Descriptor* descriptor,
const Options& options,
const std::vector<int>& has_bit_indices,
MessageSCCAnalyzer* scc_analyzer) {
std::vector<const FieldDescriptor*> ordered_fields =
GetOrderedFields(descriptor, options);
// The table size is rounded up to the nearest power of 2, clamping at 2^5.
// Note that this is a naive approach: a better approach should only consider
// table-eligible fields. We may also want to push rarely-encountered fields
// into the fallback, to make the table smaller.
table_size_log2 = ordered_fields.size() >= 16 ? 5
: ordered_fields.size() >= 8 ? 4
: ordered_fields.size() >= 4 ? 3
: ordered_fields.size() >= 2 ? 2
: 1;
const unsigned table_size = 1 << table_size_log2;
// Construct info for each possible entry. Fields that do not use table-driven
// parsing will still have an entry that nominates the fallback function.
fast_path_fields.resize(table_size);
for (const auto* field : ordered_fields) {
// Eagerly assume slow path. If we can handle this field on the fast path,
// we will pop its entry from `fallback_fields`.
fallback_fields.push_back(field);
// Anything difficult slow path:
if (field->is_map()) continue;
if (field->real_containing_oneof()) continue;
if (field->options().lazy()) continue;
if (field->options().weak()) continue;
if (IsImplicitWeakField(field, options, scc_analyzer)) continue;
// The largest tag that can be read by the tailcall parser is two bytes
// when varint-coded. This allows 14 bits for the numeric tag value:
// byte 0 byte 1
// 1nnnnttt 0nnnnnnn
// ^^^^^^^ ^^^^^^^
uint32_t tag = WireFormat::MakeTag(field);
if (tag >= 1 << 14) {
continue;
} else if (tag >= 1 << 7) {
tag = ((tag << 1) & 0x7F00) | 0x80 | (tag & 0x7F);
}
// The field index is determined by the low bits of the field number, where
// the table size determines the width of the mask. The largest table
// supported is 32 entries. The parse loop uses these bits directly, so that
// the dispatch does not require arithmetic:
// byte 0 byte 1
// 1nnnnttt 0nnnnnnn
// ^^^^^
// This means that any field number that does not fit in the lower 4 bits
// will always have the top bit of its table index asserted:
uint32_t idx = (tag >> 3) & (table_size - 1);
// If this entry in the table is already used, then this field will be
// handled by the generated fallback function.
if (!fast_path_fields[idx].func_name.empty()) continue;
// Determine the hasbit mask for this field, if needed. (Note that fields
// without hasbits use different parse functions.)
int hasbit_idx;
if (HasHasbit(field)) {
hasbit_idx = has_bit_indices[field->index()];
GOOGLE_CHECK_NE(-1, hasbit_idx) << field->DebugString();
// The tailcall parser can only update the first 32 hasbits. If this
// field's has-bit is beyond that, then it will need to be handled by the
// fallback parse function.
if (hasbit_idx >= 32) continue;
} else {
// The tailcall parser only ever syncs 32 has-bits, so if there is no
// presence, set a bit that will not be used.
hasbit_idx = 63;
}
// Determine the name of the fastpath parse function to use for this field.
std::string name;
switch (field->type()) {
case FieldDescriptor::TYPE_MESSAGE:
name = MessageParseFunctionName(field, options);
break;
case FieldDescriptor::TYPE_FIXED64:
case FieldDescriptor::TYPE_FIXED32:
case FieldDescriptor::TYPE_SFIXED64:
case FieldDescriptor::TYPE_SFIXED32:
case FieldDescriptor::TYPE_DOUBLE:
case FieldDescriptor::TYPE_FLOAT:
name = FieldParseFunctionName(field, options, table_size_log2);
break;
default:
break;
}
if (name.empty()) {
continue;
}
// This field made it into the fast path, so remove it from the fallback
// fields and fill in the table entry.
fallback_fields.pop_back();
fast_path_fields[idx].func_name = name;
fast_path_fields[idx].bits = TcFieldData(tag, hasbit_idx, 0);
fast_path_fields[idx].field = field;
}
// Construct a mask of has-bits for required fields numbered <= 32.
has_hasbits_required_mask = 0;
for (auto field : FieldRange(descriptor)) {
if (field->is_required()) {
int idx = has_bit_indices[field->index()];
if (idx >= 32) continue;
has_hasbits_required_mask |= 1u << idx;
}
}
// If there are no fallback fields, and at most one extension range, the
// parser can use a generic fallback function. Otherwise, a message-specific
// fallback routine is needed.
use_generated_fallback =
!fallback_fields.empty() || descriptor->extension_range_count() > 1;
}
ParseFunctionGenerator::ParseFunctionGenerator(
const Descriptor* descriptor, int max_has_bit_index,
const std::vector<int>& has_bit_indices, const Options& options,
MessageSCCAnalyzer* scc_analyzer,
const std::map<std::string, std::string>& vars)
: descriptor_(descriptor),
scc_analyzer_(scc_analyzer),
options_(options),
num_hasbits_(num_hasbits) {
variables_(vars),
num_hasbits_(max_has_bit_index) {
if (IsTcTableGuarded(options_) || IsTcTableEnabled(options_)) {
tc_table_info_.reset(new TailCallTableInfo(descriptor_, options_,
has_bit_indices, scc_analyzer));
}
SetCommonVars(options_, &variables_);
SetUnknkownFieldsVariable(descriptor_, options_, &variables_);
SetUnknownFieldsVariable(descriptor_, options_, &variables_);
variables_["classname"] = ClassName(descriptor, false);
}
void ParseFunctionGenerator::GenerateMethodDecls(io::Printer* printer) {
Formatter format(printer, variables_);
if (IsTCTableGuarded(options_)) {
if (IsTcTableGuarded(options_)) {
format.Outdent();
format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n");
format.Indent();
}
if (IsTCTableGuarded(options_) || IsTCTableEnabled(options_)) {
format.Outdent();
format("#error Tail Call Table parsing not yet implemented.\n");
format.Indent();
}
if (IsTCTableGuarded(options_)) {
format.Outdent();
format("#else\n");
format.Indent();
}
if (IsTCTableGuarded(options_) || IsTCTableDisabled(options_)) {
format(
"const char* _InternalParse(const char* ptr, "
"::$proto_ns$::internal::ParseContext* ctx) final;\n");
if (IsTcTableGuarded(options_) || IsTcTableEnabled(options_)) {
if (tc_table_info_->use_generated_fallback) {
format(
"static const char* Tct_ParseFallback(\n"
" ::google::protobuf::MessageLite *msg, const char *ptr,\n"
" ::google::protobuf::internal::ParseContext *ctx,\n"
" const ::google::protobuf::internal::TailCallParseTableBase *table,\n"
" uint64_t hasbits, ::google::protobuf::internal::TcFieldData data);\n"
"inline const char* Tct_FallbackImpl(\n"
" const char* ptr, ::$proto_ns$::internal::ParseContext* ctx,\n"
" const void*, $uint64$ hasbits);\n");
}
}
if (IsTCTableGuarded(options_)) {
if (IsTcTableGuarded(options_)) {
format.Outdent();
format("#endif\n");
format.Indent();
}
format(
"const char* _InternalParse(const char* ptr, "
"::$proto_ns$::internal::ParseContext* ctx) final;\n");
}
void ParseFunctionGenerator::GenerateMethodImpls(io::Printer* printer) {
@ -121,24 +289,107 @@ void ParseFunctionGenerator::GenerateMethodImpls(io::Printer* printer) {
format(
"const char* $classname$::_InternalParse(const char* ptr,\n"
" ::$proto_ns$::internal::ParseContext* ctx) {\n"
"$annotate_deserialize$"
" return _extensions_.ParseMessageSet(ptr, \n"
" internal_default_instance(), &_internal_metadata_, ctx);\n"
"}\n");
return;
}
if (IsTCTableGuarded(options_)) {
format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n");
if (IsTcTableGuarded(options_)) {
format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n\n");
}
if (IsTCTableGuarded(options_) || IsTCTableEnabled(options_)) {
format("#error Tail Call Table parsing not yet implemented.\n");
if (IsTcTableGuarded(options_) || IsTcTableEnabled(options_)) {
format(
"const char* $classname$::_InternalParse(\n"
" const char* ptr, ::$proto_ns$::internal::ParseContext* ctx) {\n"
" return ::$proto_ns$::internal::TcParser<$1$>::ParseLoop(\n"
" this, ptr, ctx, &_table_.header);\n"
"}\n"
"\n",
tc_table_info_->table_size_log2);
if (tc_table_info_->use_generated_fallback) {
GenerateTailcallFallbackFunction(format);
}
}
if (IsTCTableGuarded(options_)) {
format("#else // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n");
if (IsTcTableGuarded(options_)) {
format("\n#else // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n\n");
}
if (IsTCTableGuarded(options_) || IsTCTableDisabled(options_)) {
if (IsTcTableGuarded(options_) || IsTcTableDisabled(options_)) {
GenerateLoopingParseFunction(format);
}
if (IsTCTableGuarded(options_)) {
if (IsTcTableGuarded(options_)) {
format("\n#endif // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n");
}
}
void ParseFunctionGenerator::GenerateTailcallFallbackFunction(
Formatter& format) {
format(
"const char* $classname$::Tct_ParseFallback(PROTOBUF_TC_PARAM_DECL) {\n"
" return static_cast<$classname$*>(msg)->Tct_FallbackImpl(ptr, ctx, "
"table, hasbits);\n"
"}\n\n");
format(
"const char* $classname$::Tct_FallbackImpl(const char* ptr, "
"::$proto_ns$::internal::ParseContext* ctx, const void*, "
"$uint64$ hasbits) {\n"
"#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) return nullptr\n");
format.Indent();
if (num_hasbits_ > 0) {
// Sync hasbits
format("_has_bits_[0] = hasbits;\n");
}
format.Set("has_bits", "_has_bits_");
format.Set("continue", "goto success");
GenerateParseIterationBody(format, descriptor_,
tc_table_info_->fallback_fields);
format.Outdent();
format("success:\n");
format(" return ptr;\n");
format(
"#undef CHK_\n"
"}\n");
}
void ParseFunctionGenerator::GenerateDataDecls(io::Printer* printer) {
if (descriptor_->options().message_set_wire_format()) {
return;
}
Formatter format(printer, variables_);
if (IsTcTableGuarded(options_)) {
format.Outdent();
format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n");
format.Indent();
}
if (IsTcTableGuarded(options_) || IsTcTableEnabled(options_)) {
format(
"static const ::$proto_ns$::internal::TailCallParseTable<$1$>\n"
" _table_;\n",
tc_table_info_->table_size_log2);
}
if (IsTcTableGuarded(options_)) {
format.Outdent();
format("#endif // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n");
format.Indent();
}
}
void ParseFunctionGenerator::GenerateDataDefinitions(io::Printer* printer) {
if (descriptor_->options().message_set_wire_format()) {
return;
}
Formatter format(printer, variables_);
if (IsTcTableGuarded(options_)) {
format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n");
}
if (IsTcTableGuarded(options_) || IsTcTableEnabled(options_)) {
GenerateTailCallTable(format);
}
if (IsTcTableGuarded(options_)) {
format("#endif // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n");
}
}
@ -147,6 +398,7 @@ void ParseFunctionGenerator::GenerateLoopingParseFunction(Formatter& format) {
format(
"const char* $classname$::_InternalParse(const char* ptr, "
"::$proto_ns$::internal::ParseContext* ctx) {\n"
"$annotate_deserialize$"
"#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure\n");
format.Indent();
int hasbits_size = 0;
@ -184,6 +436,79 @@ void ParseFunctionGenerator::GenerateLoopingParseFunction(Formatter& format) {
"}\n");
}
void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) {
// All entries without a fast-path parsing function need a fallback.
std::string fallback;
if (tc_table_info_->use_generated_fallback) {
fallback = ClassName(descriptor_) + "::Tct_ParseFallback";
} else {
fallback = "::" + ProtobufNamespace(options_) +
"::internal::TcParserBase::GenericFallback";
if (GetOptimizeFor(descriptor_->file(), options_) ==
FileOptions::LITE_RUNTIME) {
fallback += "Lite";
}
}
// For simplicity and speed, the table is not covering all proto
// configurations. This model uses a fallback to cover all situations that
// the table can't accommodate, together with unknown fields or extensions.
// These are number of fields over 32, fields with 3 or more tag bytes,
// maps, weak fields, lazy, more than 1 extension range. In the cases
// the table is sufficient we can use a generic routine, that just handles
// unknown fields and potentially an extension range.
format(
"const ::$proto_ns$::internal::TailCallParseTable<$1$>\n"
" $classname$::_table_ = {\n",
tc_table_info_->table_size_log2);
format.Indent();
format("{\n");
format.Indent();
if (num_hasbits_ > 0 || IsMapEntryMessage(descriptor_)) {
format("PROTOBUF_FIELD_OFFSET($classname$, _has_bits_),\n");
} else {
format("0, // no _has_bits_\n");
}
if (descriptor_->extension_range_count() == 1) {
format(
"PROTOBUF_FIELD_OFFSET($classname$, _extensions_),\n"
"$1$, $2$, // extension_range_{low,high}\n",
descriptor_->extension_range(0)->start,
descriptor_->extension_range(0)->end);
} else {
format("0, 0, 0, // no _extensions_\n");
}
format(
"$1$, // has_bits_required_mask\n"
"&$2$._instance,\n"
"$3$ // fallback\n",
tc_table_info_->has_hasbits_required_mask,
DefaultInstanceName(descriptor_, options_), fallback);
format.Outdent();
format("}, {\n");
format.Indent();
for (const auto& info : tc_table_info_->fast_path_fields) {
if (info.field != nullptr) {
PrintFieldComment(format, info.field);
}
format("{$1$, ", info.func_name.empty() ? fallback : info.func_name);
if (info.bits.data) {
GOOGLE_DCHECK_NE(nullptr, info.field);
format(
"{$1$, $2$, "
"static_cast<uint16_t>(PROTOBUF_FIELD_OFFSET($classname$, $3$_))}",
info.bits.coded_tag(), info.bits.hasbit_idx(), FieldName(info.field));
} else {
format("{}");
}
format("},\n");
}
format.Outdent();
format("},\n"); // entries[]
format.Outdent();
format("};\n\n"); // _table_
}
void ParseFunctionGenerator::GenerateArenaString(Formatter& format,
const FieldDescriptor* field) {
if (HasHasbit(field)) {
@ -611,6 +936,176 @@ void ParseFunctionGenerator::GenerateParseIterationBody(
if (!ordered_fields.empty()) format("} // switch\n");
}
namespace {
std::string FieldParseFunctionName(const FieldDescriptor* field,
const Options& options,
uint32_t table_size_log2) {
ParseCardinality card = //
field->is_packed() ? ParseCardinality::kPacked
: field->is_repeated() ? ParseCardinality::kRepeated
: field->real_containing_oneof() ? ParseCardinality::kOneof
: ParseCardinality::kSingular;
TypeFormat type_format;
switch (field->type()) {
case FieldDescriptor::TYPE_FIXED64:
case FieldDescriptor::TYPE_SFIXED64:
case FieldDescriptor::TYPE_DOUBLE:
type_format = TypeFormat::kFixed64;
break;
case FieldDescriptor::TYPE_FIXED32:
case FieldDescriptor::TYPE_SFIXED32:
case FieldDescriptor::TYPE_FLOAT:
type_format = TypeFormat::kFixed32;
break;
case FieldDescriptor::TYPE_INT64:
case FieldDescriptor::TYPE_UINT64:
type_format = TypeFormat::kVar64;
break;
case FieldDescriptor::TYPE_INT32:
case FieldDescriptor::TYPE_UINT32:
type_format = TypeFormat::kVar32;
break;
case FieldDescriptor::TYPE_SINT64:
type_format = TypeFormat::kSInt64;
break;
case FieldDescriptor::TYPE_SINT32:
type_format = TypeFormat::kSInt32;
break;
case FieldDescriptor::TYPE_BOOL:
type_format = TypeFormat::kBool;
break;
case FieldDescriptor::TYPE_BYTES:
type_format = TypeFormat::kBytes;
break;
case FieldDescriptor::TYPE_STRING:
type_format = TypeFormat::kString;
break;
case FieldDescriptor::TYPE_GROUP:
case FieldDescriptor::TYPE_MESSAGE:
case FieldDescriptor::TYPE_ENUM:
GOOGLE_LOG(DFATAL) << "Type not handled: " << field->DebugString();
return "";
}
return "::" + ProtobufNamespace(options) + "::internal::" +
GetTailCallFieldHandlerName(card, type_format, table_size_log2,
TagSize(field->number()));
}
} // namespace
std::string GetTailCallFieldHandlerName(ParseCardinality card,
TypeFormat type_format,
int table_size_log2,
int tag_length_bytes) {
std::string name;
switch (card) {
case ParseCardinality::kPacked:
case ParseCardinality::kRepeated:
name = "TcParserBase::";
break;
case ParseCardinality::kSingular:
case ParseCardinality::kOneof:
switch (type_format) {
case TypeFormat::kBytes:
case TypeFormat::kString:
case TypeFormat::kStringValidateOnly:
name = "TcParserBase::";
break;
default:
name = StrCat("TcParser<", table_size_log2, ">::");
break;
}
}
// The field implementation functions are prefixed by cardinality:
// `Singular` for optional or implicit fields.
// `Repeated` for non-packed repeated.
// `Packed` for packed repeated.
switch (card) {
case ParseCardinality::kSingular:
name.append("Singular");
break;
case ParseCardinality::kOneof:
name.append("Oneof");
break;
case ParseCardinality::kRepeated:
name.append("Repeated");
break;
case ParseCardinality::kPacked:
name.append("Packed");
break;
}
// Next in the function name is the TypeFormat-specific name.
switch (type_format) {
case TypeFormat::kFixed64:
case TypeFormat::kFixed32:
name.append("Fixed");
break;
default:
break;
}
name.append("<");
// Determine the numeric layout type for the parser to use, independent of
// the specific parsing logic used.
switch (type_format) {
case TypeFormat::kVar64:
case TypeFormat::kFixed64:
name.append("uint64_t");
break;
case TypeFormat::kSInt64:
name.append("int64_t");
break;
case TypeFormat::kVar32:
case TypeFormat::kFixed32:
name.append("uint32_t");
break;
case TypeFormat::kSInt32:
name.append("int32_t");
break;
case TypeFormat::kBool:
name.append("bool");
break;
default:
GOOGLE_LOG(FATAL) << static_cast<int>(type_format);
return "";
}
name.append(", ");
name.append(CodedTagType(tag_length_bytes));
switch (type_format) {
default:
break;
}
name.append(">");
return name;
}
} // namespace cpp
} // namespace compiler
} // namespace protobuf

@ -39,6 +39,7 @@
#include <google/protobuf/compiler/cpp/cpp_options.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/generated_message_tctable_decl.h>
#include <google/protobuf/wire_format_lite.h>
namespace google {
@ -46,13 +47,38 @@ namespace protobuf {
namespace compiler {
namespace cpp {
// Helper class for generating tailcall parsing functions.
struct TailCallTableInfo {
TailCallTableInfo(const Descriptor* descriptor, const Options& options,
const std::vector<int>& has_bit_indices,
MessageSCCAnalyzer* scc_analyzer);
// Information to generate field entries.
struct FieldInfo {
const FieldDescriptor* field;
google::protobuf::internal::TcFieldData bits;
std::string func_name;
};
// Fields parsed by the table fast-path.
std::vector<FieldInfo> fast_path_fields;
// Fields parsed by slow-path fallback.
std::vector<const FieldDescriptor*> fallback_fields;
// Table size.
int table_size_log2;
// Mask for has-bits of required fields.
uint32_t has_hasbits_required_mask;
// True if a generated fallback function is required instead of generic.
bool use_generated_fallback;
};
// ParseFunctionGenerator generates the _InternalParse function for a message
// (and any associated supporting members).
class ParseFunctionGenerator {
public:
ParseFunctionGenerator(const Descriptor* descriptor, int num_hasbits,
ParseFunctionGenerator(const Descriptor* descriptor, int max_has_bit_index,
const std::vector<int>& has_bit_indices,
const Options& options,
MessageSCCAnalyzer* scc_analyzer);
MessageSCCAnalyzer* scc_analyzer,
const std::map<std::string, std::string>& vars);
// Emits class-level method declarations to `printer`:
void GenerateMethodDecls(io::Printer* printer);
@ -60,13 +86,22 @@ class ParseFunctionGenerator {
// Emits out-of-class method implementation definitions to `printer`:
void GenerateMethodImpls(io::Printer* printer);
// Emits class-level data member declarations to `printer`:
void GenerateDataDecls(io::Printer* printer);
// Emits out-of-class data member definitions to `printer`:
void GenerateDataDefinitions(io::Printer* printer);
private:
// Returns the proto runtime internal namespace.
std::string pi_ns();
// Generates a fallback function for tailcall table-based parsing.
void GenerateTailcallFallbackFunction(Formatter& format);
// Generates a looping `_InternalParse` function.
void GenerateLoopingParseFunction(Formatter& format);
// Generates the tail-call table definition.
void GenerateTailCallTable(Formatter& format);
// Generates parsing code for an `ArenaString` field.
void GenerateArenaString(Formatter& format, const FieldDescriptor* field);
@ -92,9 +127,50 @@ class ParseFunctionGenerator {
MessageSCCAnalyzer* scc_analyzer_;
const Options& options_;
std::map<std::string, std::string> variables_;
std::unique_ptr<TailCallTableInfo> tc_table_info_;
int num_hasbits_;
};
// Returns the integer type that holds a tag of the given length (in bytes) when
// wire-encoded.
const char* CodedTagType(int tag_size);
enum class ParseCardinality {
kSingular,
kOneof,
kRepeated,
kPacked,
};
// TypeFormat defines parsing types, which encapsulates the expected wire
// format, conversion or validation, and the in-memory layout.
enum class TypeFormat {
// Fixed types:
kFixed64, // fixed64, sfixed64, double
kFixed32, // fixed32, sfixed32, float
// Varint types:
kVar64, // int64, uint64
kVar32, // int32, uint32
kSInt64, // sint64
kSInt32, // sint32
kBool, // bool
// Length-delimited types:
kBytes, // bytes
kString, // string (proto3/UTF-8 strict)
kStringValidateOnly, // string (proto2/UTF-8 validate only)
};
// Returns the name of a field parser function.
//
// These are out-of-line functions generated by
// parse_function_inc_generator_main.
std::string GetTailCallFieldHandlerName(ParseCardinality card,
TypeFormat type_format,
int table_size_log2,
int tag_length_bytes);
} // namespace cpp
} // namespace compiler
} // namespace protobuf

@ -153,7 +153,7 @@ void PrimitiveFieldGenerator::GenerateInlineAccessorDefinitions(
" return $name$_;\n"
"}\n"
"inline $type$ $classname$::$name$() const {\n"
"$annotate_accessor$"
"$annotate_get$"
" // @@protoc_insertion_point(field_get:$full_name$)\n"
" return _internal_$name$();\n"
"}\n"
@ -162,8 +162,8 @@ void PrimitiveFieldGenerator::GenerateInlineAccessorDefinitions(
" $name$_ = value;\n"
"}\n"
"inline void $classname$::set_$name$($type$ value) {\n"
"$annotate_accessor$"
" _internal_set_$name$(value);\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n");
}
@ -252,13 +252,13 @@ void PrimitiveOneofFieldGenerator::GenerateInlineAccessorDefinitions(
" $field_member$ = value;\n"
"}\n"
"inline $type$ $classname$::$name$() const {\n"
"$annotate_accessor$"
"$annotate_get$"
" // @@protoc_insertion_point(field_get:$full_name$)\n"
" return _internal_$name$();\n"
"}\n"
"inline void $classname$::set_$name$($type$ value) {\n"
"$annotate_accessor$"
" _internal_set_$name$(value);\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n");
}
@ -338,12 +338,12 @@ void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions(
" return $name$_.Get(index);\n"
"}\n"
"inline $type$ $classname$::$name$(int index) const {\n"
"$annotate_accessor$"
"$annotate_get$"
" // @@protoc_insertion_point(field_get:$full_name$)\n"
" return _internal_$name$(index);\n"
"}\n"
"inline void $classname$::set_$name$(int index, $type$ value) {\n"
"$annotate_accessor$"
"$annotate_set$"
" $name$_.Set(index, value);\n"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n"
@ -351,8 +351,8 @@ void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions(
" $name$_.Add(value);\n"
"}\n"
"inline void $classname$::add_$name$($type$ value) {\n"
"$annotate_accessor$"
" _internal_add_$name$(value);\n"
"$annotate_add$"
" // @@protoc_insertion_point(field_add:$full_name$)\n"
"}\n"
"inline const ::$proto_ns$::RepeatedField< $type$ >&\n"
@ -361,7 +361,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions(
"}\n"
"inline const ::$proto_ns$::RepeatedField< $type$ >&\n"
"$classname$::$name$() const {\n"
"$annotate_accessor$"
"$annotate_list$"
" // @@protoc_insertion_point(field_list:$full_name$)\n"
" return _internal_$name$();\n"
"}\n"
@ -371,7 +371,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions(
"}\n"
"inline ::$proto_ns$::RepeatedField< $type$ >*\n"
"$classname$::mutable_$name$() {\n"
"$annotate_accessor$"
"$annotate_mutable_list$"
" // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
" return _internal_mutable_$name$();\n"
"}\n");

@ -162,7 +162,7 @@ void StringFieldGenerator::GenerateAccessorDeclarations(
descriptor_);
format(
"$deprecated_attr$std::string* ${1$mutable_$name$$}$();\n"
"PROTOBUF_FUTURE_MUST_USE_RESULT $deprecated_attr$std::string* "
"PROTOBUF_MUST_USE_RESULT $deprecated_attr$std::string* "
"${1$$release_name$$}$();\n"
"$deprecated_attr$void ${1$set_allocated_$name$$}$(std::string* "
"$name$);\n",
@ -187,7 +187,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions(
Formatter format(printer, variables_);
format(
"inline const std::string& $classname$::$name$() const {\n"
"$annotate_accessor$"
"$annotate_get$"
" // @@protoc_insertion_point(field_get:$full_name$)\n");
if (!descriptor_->default_value_string().empty()) {
format(
@ -200,16 +200,17 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions(
"template <typename ArgT0, typename... ArgT>\n"
"inline PROTOBUF_ALWAYS_INLINE\n"
"void $classname$::set_$name$(ArgT0&& arg0, ArgT... args) {\n"
"$annotate_accessor$"
" $set_hasbit$\n"
" $name$_.$setter$($default_value_tag$, static_cast<ArgT0 &&>(arg0),"
" args..., GetArenaForAllocation());\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n"
"inline std::string* $classname$::mutable_$name$() {\n"
"$annotate_accessor$"
" std::string* _s = _internal_mutable_$name$();\n"
"$annotate_mutable$"
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
" return _internal_mutable_$name$();\n"
" return _s;\n"
"}\n"
"inline const std::string& $classname$::_internal_$name$() const {\n"
" return $name$_.Get();\n"
@ -226,7 +227,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions(
"GetArenaForAllocation());\n"
"}\n"
"inline std::string* $classname$::$release_name$() {\n"
"$annotate_accessor$"
"$annotate_release$"
" // @@protoc_insertion_point(field_release:$full_name$)\n");
if (HasHasbit(descriptor_)) {
@ -245,7 +246,6 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions(
format(
"}\n"
"inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
"$annotate_accessor$"
" if ($name$ != nullptr) {\n"
" $set_hasbit$\n"
" } else {\n"
@ -253,6 +253,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions(
" }\n"
" $name$_.SetAllocated($init_value$, $name$,\n"
" GetArenaForAllocation());\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
"}\n");
}
@ -404,13 +405,12 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions(
Formatter format(printer, variables_);
format(
"inline const std::string& $classname$::$name$() const {\n"
"$annotate_accessor$"
"$annotate_get$"
" // @@protoc_insertion_point(field_get:$full_name$)\n"
" return _internal_$name$();\n"
"}\n"
"template <typename ArgT0, typename... ArgT>\n"
"inline void $classname$::set_$name$(ArgT0&& arg0, ArgT... args) {\n"
"$annotate_accessor$"
" if (!_internal_has_$name$()) {\n"
" clear_$oneof_name$();\n"
" set_has_$name$();\n"
@ -418,12 +418,14 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions(
" }\n"
" $field_member$.$setter$($default_value_tag$,"
" static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n"
"inline std::string* $classname$::mutable_$name$() {\n"
"$annotate_accessor$"
" std::string* _s = _internal_mutable_$name$();\n"
"$annotate_mutable$"
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
" return _internal_mutable_$name$();\n"
" return _s;\n"
"}\n"
"inline const std::string& $classname$::_internal_$name$() const {\n"
" if (_internal_has_$name$()) {\n"
@ -452,7 +454,7 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions(
" $default_variable_or_tag$, GetArenaForAllocation());\n"
"}\n"
"inline std::string* $classname$::$release_name$() {\n"
"$annotate_accessor$"
"$annotate_release$"
" // @@protoc_insertion_point(field_release:$full_name$)\n"
" if (_internal_has_$name$()) {\n"
" clear_has_$oneof_name$();\n"
@ -463,7 +465,6 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions(
" }\n"
"}\n"
"inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
"$annotate_accessor$"
" if (has_$oneof_name$()) {\n"
" clear_$oneof_name$();\n"
" }\n"
@ -475,6 +476,7 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions(
" arena->Own($name$);\n"
" }\n"
" }\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
"}\n");
}
@ -590,9 +592,10 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions(
Formatter format(printer, variables_);
format(
"inline std::string* $classname$::add_$name$() {\n"
"$annotate_accessor$"
" std::string* _s = _internal_add_$name$();\n"
"$annotate_add_mutable$"
" // @@protoc_insertion_point(field_add_mutable:$full_name$)\n"
" return _internal_add_$name$();\n"
" return _s;\n"
"}\n");
if (options_.safe_boundary_check) {
format(
@ -610,39 +613,39 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions(
}
format(
"inline const std::string& $classname$::$name$(int index) const {\n"
"$annotate_accessor$"
"$annotate_get$"
" // @@protoc_insertion_point(field_get:$full_name$)\n"
" return _internal_$name$(index);\n"
"}\n"
"inline std::string* $classname$::mutable_$name$(int index) {\n"
"$annotate_accessor$"
"$annotate_mutable$"
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
" return $name$_.Mutable(index);\n"
"}\n"
"inline void $classname$::set_$name$(int index, const std::string& "
"value) "
"{\n"
"$annotate_accessor$"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
" $name$_.Mutable(index)->assign(value);\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n"
"inline void $classname$::set_$name$(int index, std::string&& value) {\n"
"$annotate_accessor$"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
" $name$_.Mutable(index)->assign(std::move(value));\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n"
"inline void $classname$::set_$name$(int index, const char* value) {\n"
"$annotate_accessor$"
" $null_check$"
" $name$_.Mutable(index)->assign(value);\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set_char:$full_name$)\n"
"}\n");
if (!options_.opensource_runtime) {
format(
"inline void "
"$classname$::set_$name$(int index, StringPiece value) {\n"
"$annotate_accessor$"
" $name$_.Mutable(index)->assign(value.data(), value.size());\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
"}\n");
}
@ -650,54 +653,54 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions(
"inline void "
"$classname$::set_$name$"
"(int index, const $pointer_type$* value, size_t size) {\n"
"$annotate_accessor$"
" $name$_.Mutable(index)->assign(\n"
" reinterpret_cast<const char*>(value), size);\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
"}\n"
"inline std::string* $classname$::_internal_add_$name$() {\n"
" return $name$_.Add();\n"
"}\n"
"inline void $classname$::add_$name$(const std::string& value) {\n"
"$annotate_accessor$"
" $name$_.Add()->assign(value);\n"
"$annotate_add$"
" // @@protoc_insertion_point(field_add:$full_name$)\n"
"}\n"
"inline void $classname$::add_$name$(std::string&& value) {\n"
"$annotate_accessor$"
" $name$_.Add(std::move(value));\n"
"$annotate_add$"
" // @@protoc_insertion_point(field_add:$full_name$)\n"
"}\n"
"inline void $classname$::add_$name$(const char* value) {\n"
"$annotate_accessor$"
" $null_check$"
" $name$_.Add()->assign(value);\n"
"$annotate_add$"
" // @@protoc_insertion_point(field_add_char:$full_name$)\n"
"}\n");
if (!options_.opensource_runtime) {
format(
"inline void $classname$::add_$name$(StringPiece value) {\n"
"$annotate_accessor$"
" $name$_.Add()->assign(value.data(), value.size());\n"
"$annotate_add$"
" // @@protoc_insertion_point(field_add_string_piece:$full_name$)\n"
"}\n");
}
format(
"inline void "
"$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n"
"$annotate_accessor$"
" $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
"$annotate_add$"
" // @@protoc_insertion_point(field_add_pointer:$full_name$)\n"
"}\n"
"inline const ::$proto_ns$::RepeatedPtrField<std::string>&\n"
"$classname$::$name$() const {\n"
"$annotate_accessor$"
"$annotate_list$"
" // @@protoc_insertion_point(field_list:$full_name$)\n"
" return $name$_;\n"
"}\n"
"inline ::$proto_ns$::RepeatedPtrField<std::string>*\n"
"$classname$::mutable_$name$() {\n"
"$annotate_accessor$"
"$annotate_mutable_list$"
" // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
" return &$name$_;\n"
"}\n");

@ -202,8 +202,8 @@ class PROTOBUF_EXPORT MultiFileErrorCollector {
virtual void AddError(const std::string& filename, int line, int column,
const std::string& message) = 0;
virtual void AddWarning(const std::string& /* filename */, int /* line */, int /* column */,
const std::string& /* message */) {}
virtual void AddWarning(const std::string& /* filename */, int /* line */,
int /* column */, const std::string& /* message */) {}
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MultiFileErrorCollector);

@ -60,29 +60,30 @@ class ImmutableEnumFieldGenerator : public ImmutableFieldGenerator {
explicit ImmutableEnumFieldGenerator(const FieldDescriptor* descriptor,
int messageBitIndex, int builderBitIndex,
Context* context);
~ImmutableEnumFieldGenerator();
~ImmutableEnumFieldGenerator() override;
// implements ImmutableFieldGenerator
// ---------------------------------------
int GetNumBitsForMessage() const;
int GetNumBitsForBuilder() const;
void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
void GenerateBuilderClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
void GenerateEqualsCode(io::Printer* printer) const;
void GenerateHashCode(io::Printer* printer) const;
void GenerateKotlinDslMembers(io::Printer* printer) const;
std::string GetBoxedType() const;
int GetNumBitsForMessage() const override;
int GetNumBitsForBuilder() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
void GenerateMembers(io::Printer* printer) const override;
void GenerateBuilderMembers(io::Printer* printer) const override;
void GenerateInitializationCode(io::Printer* printer) const override;
void GenerateBuilderClearCode(io::Printer* printer) const override;
void GenerateMergingCode(io::Printer* printer) const override;
void GenerateBuildingCode(io::Printer* printer) const override;
void GenerateParsingCode(io::Printer* printer) const override;
void GenerateParsingDoneCode(io::Printer* printer) const override;
void GenerateSerializationCode(io::Printer* printer) const override;
void GenerateSerializedSizeCode(io::Printer* printer) const override;
void GenerateFieldBuilderInitializationCode(
io::Printer* printer) const override;
void GenerateEqualsCode(io::Printer* printer) const override;
void GenerateHashCode(io::Printer* printer) const override;
void GenerateKotlinDslMembers(io::Printer* printer) const override;
std::string GetBoxedType() const override;
protected:
const FieldDescriptor* descriptor_;
@ -119,29 +120,30 @@ class RepeatedImmutableEnumFieldGenerator : public ImmutableFieldGenerator {
explicit RepeatedImmutableEnumFieldGenerator(
const FieldDescriptor* descriptor, int messageBitIndex,
int builderBitIndex, Context* context);
~RepeatedImmutableEnumFieldGenerator();
~RepeatedImmutableEnumFieldGenerator() override;
// implements ImmutableFieldGenerator ---------------------------------------
int GetNumBitsForMessage() const;
int GetNumBitsForBuilder() const;
void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
void GenerateBuilderClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingCodeFromPacked(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
void GenerateEqualsCode(io::Printer* printer) const;
void GenerateHashCode(io::Printer* printer) const;
void GenerateKotlinDslMembers(io::Printer* printer) const;
std::string GetBoxedType() const;
int GetNumBitsForMessage() const override;
int GetNumBitsForBuilder() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
void GenerateMembers(io::Printer* printer) const override;
void GenerateBuilderMembers(io::Printer* printer) const override;
void GenerateInitializationCode(io::Printer* printer) const override;
void GenerateBuilderClearCode(io::Printer* printer) const override;
void GenerateMergingCode(io::Printer* printer) const override;
void GenerateBuildingCode(io::Printer* printer) const override;
void GenerateParsingCode(io::Printer* printer) const override;
void GenerateParsingCodeFromPacked(io::Printer* printer) const override;
void GenerateParsingDoneCode(io::Printer* printer) const override;
void GenerateSerializationCode(io::Printer* printer) const override;
void GenerateSerializedSizeCode(io::Printer* printer) const override;
void GenerateFieldBuilderInitializationCode(
io::Printer* printer) const override;
void GenerateEqualsCode(io::Printer* printer) const override;
void GenerateHashCode(io::Printer* printer) const override;
void GenerateKotlinDslMembers(io::Printer* printer) const override;
std::string GetBoxedType() const override;
private:
const FieldDescriptor* descriptor_;

@ -62,20 +62,20 @@ class ImmutableEnumFieldLiteGenerator : public ImmutableFieldLiteGenerator {
explicit ImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor,
int messageBitIndex,
Context* context);
~ImmutableEnumFieldLiteGenerator();
~ImmutableEnumFieldLiteGenerator() override;
// implements ImmutableFieldLiteGenerator
// ------------------------------------
int GetNumBitsForMessage() const;
void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
int GetNumBitsForMessage() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
void GenerateMembers(io::Printer* printer) const override;
void GenerateBuilderMembers(io::Printer* printer) const override;
void GenerateInitializationCode(io::Printer* printer) const override;
void GenerateFieldInfo(io::Printer* printer,
std::vector<uint16_t>* output) const;
void GenerateKotlinDslMembers(io::Printer* printer) const;
std::vector<uint16_t>* output) const override;
void GenerateKotlinDslMembers(io::Printer* printer) const override;
std::string GetBoxedType() const;
std::string GetBoxedType() const override;
protected:
const FieldDescriptor* descriptor_;
@ -93,12 +93,12 @@ class ImmutableEnumOneofFieldLiteGenerator
public:
ImmutableEnumOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
int messageBitIndex, Context* context);
~ImmutableEnumOneofFieldLiteGenerator();
~ImmutableEnumOneofFieldLiteGenerator() override;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const override;
void GenerateBuilderMembers(io::Printer* printer) const override;
void GenerateFieldInfo(io::Printer* printer,
std::vector<uint16_t>* output) const;
std::vector<uint16_t>* output) const override;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumOneofFieldLiteGenerator);
@ -109,19 +109,19 @@ class RepeatedImmutableEnumFieldLiteGenerator
public:
explicit RepeatedImmutableEnumFieldLiteGenerator(
const FieldDescriptor* descriptor, int messageBitIndex, Context* context);
~RepeatedImmutableEnumFieldLiteGenerator();
~RepeatedImmutableEnumFieldLiteGenerator() override;
// implements ImmutableFieldLiteGenerator ------------------------------------
int GetNumBitsForMessage() const;
void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
int GetNumBitsForMessage() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
void GenerateMembers(io::Printer* printer) const override;
void GenerateBuilderMembers(io::Printer* printer) const override;
void GenerateInitializationCode(io::Printer* printer) const override;
void GenerateFieldInfo(io::Printer* printer,
std::vector<uint16_t>* output) const;
void GenerateKotlinDslMembers(io::Printer* printer) const;
std::vector<uint16_t>* output) const override;
void GenerateKotlinDslMembers(io::Printer* printer) const override;
std::string GetBoxedType() const;
std::string GetBoxedType() const override;
private:
const FieldDescriptor* descriptor_;

@ -263,6 +263,20 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
(*variables)["kt_capitalized_name"] = IsForbiddenKotlin(info->name)
? info->capitalized_name + "_"
: info->capitalized_name;
if (!descriptor->is_repeated()) {
(*variables)["annotation_field_type"] = FieldTypeName(descriptor->type());
} else if (GetJavaType(descriptor) == JAVATYPE_MESSAGE &&
IsMapEntry(descriptor->message_type())) {
(*variables)["annotation_field_type"] =
std::string(FieldTypeName(descriptor->type())) + "MAP";
} else {
(*variables)["annotation_field_type"] =
std::string(FieldTypeName(descriptor->type())) + "_LIST";
if (descriptor->is_packed()) {
(*variables)["annotation_field_type"] =
(*variables)["annotation_field_type"] + "_PACKED";
}
}
}
void SetCommonOneofVariables(const FieldDescriptor* descriptor,

@ -686,7 +686,7 @@ void FileGenerator::GenerateKotlinSiblings(
for (int i = 0; i < file_->message_type_count(); i++) {
const Descriptor* descriptor = file_->message_type(i);
MessageGenerator* generator = message_generators_[i].get();
auto open_file = [context](const string& filename) {
auto open_file = [context](const std::string& filename) {
return std::unique_ptr<io::ZeroCopyOutputStream>(context->Open(filename));
};
std::string filename = package_dir + descriptor->name() + "Kt.kt";

@ -91,17 +91,6 @@ const std::unordered_set<std::string>* kReservedNames =
"transient", "try", "void", "volatile", "while",
});
// Names that should be avoided as field names in Kotlin.
// All Kotlin hard keywords are in this list.
const std::unordered_set<std::string>* kKotlinForbiddenNames =
new std::unordered_set<std::string>({
"as", "as?", "break", "class", "continue", "do", "else",
"false", "for", "fun", "if", "in", "!in", "interface",
"is", "!is", "null", "object", "package", "return", "super",
"this", "throw", "true", "try", "typealias", "typeof", "val",
"var", "when", "while",
});
bool IsForbidden(const std::string& field_name) {
for (int i = 0; i < GOOGLE_ARRAYSIZE(kForbiddenWordList); ++i) {
if (field_name == kForbiddenWordList[i]) {
@ -167,38 +156,6 @@ void PrintEnumVerifierLogic(io::Printer* printer,
StrCat(enum_verifier_string, terminating_string).c_str());
}
std::string ToCamelCase(const std::string& input, bool lower_first) {
bool capitalize_next = !lower_first;
std::string result;
result.reserve(input.size());
for (char i : input) {
if (i == '_') {
capitalize_next = true;
} else if (capitalize_next) {
result.push_back(ToUpperCh(i));
capitalize_next = false;
} else {
result.push_back(i);
}
}
// Lower-case the first letter.
if (lower_first && !result.empty()) {
result[0] = ToLowerCh(result[0]);
}
return result;
}
char ToUpperCh(char ch) {
return (ch >= 'a' && ch <= 'z') ? (ch - 'a' + 'A') : ch;
}
char ToLowerCh(char ch) {
return (ch >= 'A' && ch <= 'Z') ? (ch - 'A' + 'a') : ch;
}
std::string UnderscoresToCamelCase(const std::string& input,
bool cap_next_letter) {
GOOGLE_CHECK(!input.empty());
@ -236,6 +193,38 @@ std::string UnderscoresToCamelCase(const std::string& input,
return result;
}
std::string ToCamelCase(const std::string& input, bool lower_first) {
bool capitalize_next = !lower_first;
std::string result;
result.reserve(input.size());
for (char i : input) {
if (i == '_') {
capitalize_next = true;
} else if (capitalize_next) {
result.push_back(ToUpperCh(i));
capitalize_next = false;
} else {
result.push_back(i);
}
}
// Lower-case the first letter.
if (lower_first && !result.empty()) {
result[0] = ToLowerCh(result[0]);
}
return result;
}
char ToUpperCh(char ch) {
return (ch >= 'a' && ch <= 'z') ? (ch - 'a' + 'A') : ch;
}
char ToLowerCh(char ch) {
return (ch >= 'A' && ch <= 'Z') ? (ch - 'A' + 'a') : ch;
}
std::string UnderscoresToCamelCase(const FieldDescriptor* field) {
return UnderscoresToCamelCase(FieldName(field), false);
}
@ -261,6 +250,17 @@ std::string UnderscoresToCamelCaseCheckReserved(const FieldDescriptor* field) {
}
bool IsForbiddenKotlin(const std::string& field_name) {
// Names that should be avoided as field names in Kotlin.
// All Kotlin hard keywords are in this list.
const std::unordered_set<std::string>* kKotlinForbiddenNames =
new std::unordered_set<std::string>({
"as", "as?", "break", "class", "continue", "do",
"else", "false", "for", "fun", "if", "in",
"!in", "interface", "is", "!is", "null", "object",
"package", "return", "super", "this", "throw", "true",
"try", "typealias", "typeof", "val", "var", "when",
"while",
});
return kKotlinForbiddenNames->find(field_name) !=
kKotlinForbiddenNames->end();
}
@ -499,7 +499,6 @@ const char* KotlinTypeName(JavaType type) {
return NULL;
}
std::string GetOneofStoredType(const FieldDescriptor* field) {
const JavaType javaType = GetJavaType(field);
switch (javaType) {

@ -1,12 +1,40 @@
#include <google/protobuf/compiler/java/java_kotlin_generator.h>
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <memory>
#include <google/protobuf/compiler/java/java_kotlin_generator.h>
#include <google/protobuf/compiler/java/java_file.h>
#include <google/protobuf/compiler/java/java_helpers.h>
#include <google/protobuf/compiler/java/java_options.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/compiler/java/java_generator.h>
#include <google/protobuf/compiler/code_generator.h>
namespace google {
namespace protobuf {
@ -63,13 +91,17 @@ bool KotlinGenerator::Generate(const FileDescriptor* file,
std::vector<std::string> all_files;
std::vector<std::string> all_annotations;
std::unique_ptr<FileGenerator> file_generator(new FileGenerator(file, file_options, /* immutable_api = */ true));
std::unique_ptr<FileGenerator> file_generator;
if (file_options.generate_immutable_code) {
file_generator.reset(
new FileGenerator(file, file_options, /* immutable_api = */ true));
}
if (!file_generator->Validate(error)) {
return false;
}
auto open_file = [context](const string& filename) {
auto open_file = [context](const std::string& filename) {
return std::unique_ptr<io::ZeroCopyOutputStream>(context->Open(filename));
};
std::string package_dir = JavaPackageToDir(file_generator->java_package());
@ -126,5 +158,5 @@ bool KotlinGenerator::Generate(const FileDescriptor* file,
} // namespace java
} // namespace compiler
} //namespace protobuf
} // namespace protobuf
} // namespace google

@ -1,9 +1,41 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_KOTLIN_GENERATOR_H_
#define GOOGLE_PROTOBUF_COMPILER_JAVA_KOTLIN_GENERATOR_H_
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Generates Kotlin code for a given .proto file.
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_KOTLIN_GENERATOR_H__
#define GOOGLE_PROTOBUF_COMPILER_JAVA_KOTLIN_GENERATOR_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/port_def.inc>
namespace google {
@ -37,4 +69,4 @@ class PROTOC_EXPORT KotlinGenerator : public CodeGenerator {
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_KOTLIN_GENERATOR_H_
#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_KOTLIN_GENERATOR_H__

@ -43,26 +43,27 @@ class ImmutableMapFieldGenerator : public ImmutableFieldGenerator {
explicit ImmutableMapFieldGenerator(const FieldDescriptor* descriptor,
int messageBitIndex, int builderBitIndex,
Context* context);
~ImmutableMapFieldGenerator();
~ImmutableMapFieldGenerator() override;
// implements ImmutableFieldGenerator ---------------------------------------
int GetNumBitsForMessage() const;
int GetNumBitsForBuilder() const;
void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
void GenerateBuilderClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
void GenerateEqualsCode(io::Printer* printer) const;
void GenerateHashCode(io::Printer* printer) const;
void GenerateKotlinDslMembers(io::Printer* printer) const;
int GetNumBitsForMessage() const override;
int GetNumBitsForBuilder() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
void GenerateMembers(io::Printer* printer) const override;
void GenerateBuilderMembers(io::Printer* printer) const override;
void GenerateInitializationCode(io::Printer* printer) const override;
void GenerateBuilderClearCode(io::Printer* printer) const override;
void GenerateMergingCode(io::Printer* printer) const override;
void GenerateBuildingCode(io::Printer* printer) const override;
void GenerateParsingCode(io::Printer* printer) const override;
void GenerateParsingDoneCode(io::Printer* printer) const override;
void GenerateSerializationCode(io::Printer* printer) const override;
void GenerateSerializedSizeCode(io::Printer* printer) const override;
void GenerateFieldBuilderInitializationCode(
io::Printer* printer) const override;
void GenerateEqualsCode(io::Printer* printer) const override;
void GenerateHashCode(io::Printer* printer) const override;
void GenerateKotlinDslMembers(io::Printer* printer) const override;
std::string GetBoxedType() const;

@ -45,19 +45,19 @@ class ImmutableMapFieldLiteGenerator : public ImmutableFieldLiteGenerator {
explicit ImmutableMapFieldLiteGenerator(const FieldDescriptor* descriptor,
int messageBitIndex,
Context* context);
~ImmutableMapFieldLiteGenerator();
~ImmutableMapFieldLiteGenerator() override;
// implements ImmutableFieldLiteGenerator ------------------------------------
int GetNumBitsForMessage() const;
void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
int GetNumBitsForMessage() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
void GenerateMembers(io::Printer* printer) const override;
void GenerateBuilderMembers(io::Printer* printer) const override;
void GenerateInitializationCode(io::Printer* printer) const override;
void GenerateFieldInfo(io::Printer* printer,
std::vector<uint16_t>* output) const;
void GenerateKotlinDslMembers(io::Printer* printer) const;
std::vector<uint16_t>* output) const override;
void GenerateKotlinDslMembers(io::Printer* printer) const override;
std::string GetBoxedType() const;
std::string GetBoxedType() const override;
private:
const FieldDescriptor* descriptor_;

@ -1367,6 +1367,41 @@ void ImmutableMessageGenerator::GenerateInitializers(io::Printer* printer) {
}
}
// ===================================================================
void ImmutableMessageGenerator::GenerateMutableCopy(io::Printer* printer) {
printer->Print(
"protected com.google.protobuf.MutableMessage\n"
" internalMutableDefault() {\n"
" return MutableDefaultLoader.get();\n"
"}\n"
"\n"
"private static final class MutableDefaultLoader {\n"
" private static final java.lang.Object defaultOrRuntimeException;\n"
" static {\n"
" java.lang.Object local;\n"
" try {\n"
" local = internalMutableDefault(\"$mutable_name$\");\n"
" } catch (java.lang.RuntimeException e) {\n"
" local = e;\n"
" }\n"
" defaultOrRuntimeException = local;\n"
" }\n"
"\n"
" private MutableDefaultLoader() {}\n"
"\n"
" public static com.google.protobuf.MutableMessage get() {\n"
" if (defaultOrRuntimeException\n"
" instanceof java.lang.RuntimeException) {\n"
" throw (java.lang.RuntimeException) defaultOrRuntimeException;\n"
" }\n"
" return\n"
" (com.google.protobuf.MutableMessage) "
"defaultOrRuntimeException;\n"
" }\n"
"}\n",
"mutable_name", name_resolver_->GetJavaMutableClassName(descriptor_));
}
void ImmutableMessageGenerator::GenerateKotlinDsl(io::Printer* printer) const {
printer->Print(
"@kotlin.OptIn"

@ -102,14 +102,14 @@ class ImmutableMessageGenerator : public MessageGenerator {
ImmutableMessageGenerator(const Descriptor* descriptor, Context* context);
virtual ~ImmutableMessageGenerator();
virtual void Generate(io::Printer* printer);
virtual void GenerateInterface(io::Printer* printer);
virtual void GenerateExtensionRegistrationCode(io::Printer* printer);
virtual void GenerateStaticVariables(io::Printer* printer,
int* bytecode_estimate);
void Generate(io::Printer* printer) override;
void GenerateInterface(io::Printer* printer) override;
void GenerateExtensionRegistrationCode(io::Printer* printer) override;
void GenerateStaticVariables(io::Printer* printer,
int* bytecode_estimate) override;
// Returns an estimate of the number of bytes the printed code will compile to
virtual int GenerateStaticVariableInitializers(io::Printer* printer);
int GenerateStaticVariableInitializers(io::Printer* printer) override;
void GenerateKotlinDsl(io::Printer* printer) const override;
void GenerateKotlinMembers(io::Printer* printer) const override;
void GenerateTopLevelKotlinMembers(io::Printer* printer) const override;
@ -134,6 +134,7 @@ class ImmutableMessageGenerator : public MessageGenerator {
void GenerateEqualsAndHashCode(io::Printer* printer);
void GenerateParser(io::Printer* printer);
void GenerateParsingConstructor(io::Printer* printer);
void GenerateMutableCopy(io::Printer* printer);
void GenerateKotlinExtensions(io::Printer* printer) const;
void GenerateAnyMethods(io::Printer* printer);

@ -128,28 +128,29 @@ class RepeatedImmutableMessageFieldGenerator : public ImmutableFieldGenerator {
explicit RepeatedImmutableMessageFieldGenerator(
const FieldDescriptor* descriptor, int messageBitIndex,
int builderBitIndex, Context* context);
~RepeatedImmutableMessageFieldGenerator();
~RepeatedImmutableMessageFieldGenerator() override;
// implements ImmutableFieldGenerator ---------------------------------------
int GetNumBitsForMessage() const;
int GetNumBitsForBuilder() const;
void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
void GenerateBuilderClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
void GenerateEqualsCode(io::Printer* printer) const;
void GenerateHashCode(io::Printer* printer) const;
void GenerateKotlinDslMembers(io::Printer* printer) const;
std::string GetBoxedType() const;
int GetNumBitsForMessage() const override;
int GetNumBitsForBuilder() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
void GenerateMembers(io::Printer* printer) const override;
void GenerateBuilderMembers(io::Printer* printer) const override;
void GenerateInitializationCode(io::Printer* printer) const override;
void GenerateBuilderClearCode(io::Printer* printer) const override;
void GenerateMergingCode(io::Printer* printer) const override;
void GenerateBuildingCode(io::Printer* printer) const override;
void GenerateParsingCode(io::Printer* printer) const override;
void GenerateParsingDoneCode(io::Printer* printer) const override;
void GenerateSerializationCode(io::Printer* printer) const override;
void GenerateSerializedSizeCode(io::Printer* printer) const override;
void GenerateFieldBuilderInitializationCode(
io::Printer* printer) const override;
void GenerateEqualsCode(io::Printer* printer) const override;
void GenerateHashCode(io::Printer* printer) const override;
void GenerateKotlinDslMembers(io::Printer* printer) const override;
std::string GetBoxedType() const override;
protected:
const FieldDescriptor* descriptor_;

@ -109,19 +109,19 @@ class RepeatedImmutableMessageFieldLiteGenerator
public:
explicit RepeatedImmutableMessageFieldLiteGenerator(
const FieldDescriptor* descriptor, int messageBitIndex, Context* context);
~RepeatedImmutableMessageFieldLiteGenerator();
~RepeatedImmutableMessageFieldLiteGenerator() override;
// implements ImmutableFieldLiteGenerator ------------------------------------
int GetNumBitsForMessage() const;
void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
int GetNumBitsForMessage() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
void GenerateMembers(io::Printer* printer) const override;
void GenerateBuilderMembers(io::Printer* printer) const override;
void GenerateInitializationCode(io::Printer* printer) const override;
void GenerateFieldInfo(io::Printer* printer,
std::vector<uint16_t>* output) const;
void GenerateKotlinDslMembers(io::Printer* printer) const;
std::vector<uint16_t>* output) const override;
void GenerateKotlinDslMembers(io::Printer* printer) const override;
std::string GetBoxedType() const;
std::string GetBoxedType() const override;
protected:
const FieldDescriptor* descriptor_;

@ -350,6 +350,29 @@ std::string ClassNameResolver::GetKotlinExtensionsClassName(
descriptor->file(), true, true, true);
}
std::string ClassNameResolver::GetJavaMutableClassName(
const Descriptor* descriptor) {
return GetJavaClassFullName(ClassNameWithoutPackage(descriptor, false),
descriptor->file(), false);
}
std::string ClassNameResolver::GetJavaMutableClassName(
const EnumDescriptor* descriptor) {
return GetJavaClassFullName(ClassNameWithoutPackage(descriptor, false),
descriptor->file(), false);
}
std::string ClassNameResolver::GetDowngradedFileClassName(
const FileDescriptor* file) {
return "Downgraded" + GetFileClassName(file, false);
}
std::string ClassNameResolver::GetDowngradedClassName(
const Descriptor* descriptor) {
return FileJavaPackage(descriptor->file()) + "." +
GetDowngradedFileClassName(descriptor->file()) + "." +
ClassNameWithoutPackage(descriptor, false);
}
} // namespace java
} // namespace compiler

@ -117,6 +117,12 @@ class ClassNameResolver {
std::string GetJavaImmutableClassName(const EnumDescriptor* descriptor);
std::string GetKotlinFactoryName(const Descriptor* descriptor);
std::string GetKotlinExtensionsClassName(const Descriptor* descriptor);
std::string GetJavaMutableClassName(const Descriptor* descriptor);
std::string GetJavaMutableClassName(const EnumDescriptor* descriptor);
// Gets the outer class and the actual class for downgraded mutable messages.
std::string GetDowngradedFileClassName(const FileDescriptor* file);
std::string GetDowngradedClassName(const Descriptor* descriptor);
private:
// Get the full name of a Java class by prepending the Java package name
// or outer class name.

@ -54,7 +54,6 @@ namespace compiler {
namespace java {
using internal::WireFormat;
using internal::WireFormatLite;
namespace {

@ -61,29 +61,30 @@ class ImmutablePrimitiveFieldGenerator : public ImmutableFieldGenerator {
int messageBitIndex,
int builderBitIndex,
Context* context);
~ImmutablePrimitiveFieldGenerator();
~ImmutablePrimitiveFieldGenerator() override;
// implements ImmutableFieldGenerator
// ---------------------------------------
int GetNumBitsForMessage() const;
int GetNumBitsForBuilder() const;
void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
void GenerateBuilderClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
void GenerateEqualsCode(io::Printer* printer) const;
void GenerateHashCode(io::Printer* printer) const;
void GenerateKotlinDslMembers(io::Printer* printer) const;
std::string GetBoxedType() const;
int GetNumBitsForMessage() const override;
int GetNumBitsForBuilder() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
void GenerateMembers(io::Printer* printer) const override;
void GenerateBuilderMembers(io::Printer* printer) const override;
void GenerateInitializationCode(io::Printer* printer) const override;
void GenerateBuilderClearCode(io::Printer* printer) const override;
void GenerateMergingCode(io::Printer* printer) const override;
void GenerateBuildingCode(io::Printer* printer) const override;
void GenerateParsingCode(io::Printer* printer) const override;
void GenerateParsingDoneCode(io::Printer* printer) const override;
void GenerateSerializationCode(io::Printer* printer) const override;
void GenerateSerializedSizeCode(io::Printer* printer) const override;
void GenerateFieldBuilderInitializationCode(
io::Printer* printer) const override;
void GenerateEqualsCode(io::Printer* printer) const override;
void GenerateHashCode(io::Printer* printer) const override;
void GenerateKotlinDslMembers(io::Printer* printer) const override;
std::string GetBoxedType() const override;
protected:
const FieldDescriptor* descriptor_;
@ -120,29 +121,30 @@ class RepeatedImmutablePrimitiveFieldGenerator
explicit RepeatedImmutablePrimitiveFieldGenerator(
const FieldDescriptor* descriptor, int messageBitIndex,
int builderBitIndex, Context* context);
virtual ~RepeatedImmutablePrimitiveFieldGenerator();
~RepeatedImmutablePrimitiveFieldGenerator() override;
// implements ImmutableFieldGenerator ---------------------------------------
int GetNumBitsForMessage() const;
int GetNumBitsForBuilder() const;
void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
void GenerateBuilderClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingCodeFromPacked(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
void GenerateEqualsCode(io::Printer* printer) const;
void GenerateHashCode(io::Printer* printer) const;
void GenerateKotlinDslMembers(io::Printer* printer) const;
std::string GetBoxedType() const;
int GetNumBitsForMessage() const override;
int GetNumBitsForBuilder() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
void GenerateMembers(io::Printer* printer) const override;
void GenerateBuilderMembers(io::Printer* printer) const override;
void GenerateInitializationCode(io::Printer* printer) const override;
void GenerateBuilderClearCode(io::Printer* printer) const override;
void GenerateMergingCode(io::Printer* printer) const override;
void GenerateBuildingCode(io::Printer* printer) const override;
void GenerateParsingCode(io::Printer* printer) const override;
void GenerateParsingCodeFromPacked(io::Printer* printer) const override;
void GenerateParsingDoneCode(io::Printer* printer) const override;
void GenerateSerializationCode(io::Printer* printer) const override;
void GenerateSerializedSizeCode(io::Printer* printer) const override;
void GenerateFieldBuilderInitializationCode(
io::Printer* printer) const override;
void GenerateEqualsCode(io::Printer* printer) const override;
void GenerateHashCode(io::Printer* printer) const override;
void GenerateKotlinDslMembers(io::Printer* printer) const override;
std::string GetBoxedType() const override;
private:
const FieldDescriptor* descriptor_;

@ -62,20 +62,20 @@ class ImmutablePrimitiveFieldLiteGenerator
public:
explicit ImmutablePrimitiveFieldLiteGenerator(
const FieldDescriptor* descriptor, int messageBitIndex, Context* context);
~ImmutablePrimitiveFieldLiteGenerator();
~ImmutablePrimitiveFieldLiteGenerator() override;
// implements ImmutableFieldLiteGenerator
// ------------------------------------
int GetNumBitsForMessage() const;
void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
int GetNumBitsForMessage() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
void GenerateMembers(io::Printer* printer) const override;
void GenerateBuilderMembers(io::Printer* printer) const override;
void GenerateInitializationCode(io::Printer* printer) const override;
void GenerateFieldInfo(io::Printer* printer,
std::vector<uint16_t>* output) const;
void GenerateKotlinDslMembers(io::Printer* printer) const;
std::vector<uint16_t>* output) const override;
void GenerateKotlinDslMembers(io::Printer* printer) const override;
std::string GetBoxedType() const;
std::string GetBoxedType() const override;
protected:
const FieldDescriptor* descriptor_;
@ -110,19 +110,19 @@ class RepeatedImmutablePrimitiveFieldLiteGenerator
public:
explicit RepeatedImmutablePrimitiveFieldLiteGenerator(
const FieldDescriptor* descriptor, int messageBitIndex, Context* context);
virtual ~RepeatedImmutablePrimitiveFieldLiteGenerator();
~RepeatedImmutablePrimitiveFieldLiteGenerator() override;
// implements ImmutableFieldLiteGenerator ------------------------------------
int GetNumBitsForMessage() const;
void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
int GetNumBitsForMessage() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
void GenerateMembers(io::Printer* printer) const override;
void GenerateBuilderMembers(io::Printer* printer) const override;
void GenerateInitializationCode(io::Printer* printer) const override;
void GenerateFieldInfo(io::Printer* printer,
std::vector<uint16_t>* output) const;
void GenerateKotlinDslMembers(io::Printer* printer) const;
std::string GetBoxedType() const;
std::vector<uint16_t>* output) const override;
void GenerateKotlinDslMembers(io::Printer* printer) const override;
std::string GetBoxedType() const override;
private:
const FieldDescriptor* descriptor_;

@ -119,28 +119,29 @@ class RepeatedImmutableStringFieldGenerator : public ImmutableFieldGenerator {
explicit RepeatedImmutableStringFieldGenerator(
const FieldDescriptor* descriptor, int messageBitIndex,
int builderBitIndex, Context* context);
~RepeatedImmutableStringFieldGenerator();
~RepeatedImmutableStringFieldGenerator() override;
// implements ImmutableFieldGenerator ---------------------------------------
int GetNumBitsForMessage() const;
int GetNumBitsForBuilder() const;
void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
void GenerateBuilderClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
void GenerateEqualsCode(io::Printer* printer) const;
void GenerateHashCode(io::Printer* printer) const;
void GenerateKotlinDslMembers(io::Printer* printer) const;
std::string GetBoxedType() const;
int GetNumBitsForMessage() const override;
int GetNumBitsForBuilder() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
void GenerateMembers(io::Printer* printer) const override;
void GenerateBuilderMembers(io::Printer* printer) const override;
void GenerateInitializationCode(io::Printer* printer) const override;
void GenerateBuilderClearCode(io::Printer* printer) const override;
void GenerateMergingCode(io::Printer* printer) const override;
void GenerateBuildingCode(io::Printer* printer) const override;
void GenerateParsingCode(io::Printer* printer) const override;
void GenerateParsingDoneCode(io::Printer* printer) const override;
void GenerateSerializationCode(io::Printer* printer) const override;
void GenerateSerializedSizeCode(io::Printer* printer) const override;
void GenerateFieldBuilderInitializationCode(
io::Printer* printer) const override;
void GenerateEqualsCode(io::Printer* printer) const override;
void GenerateHashCode(io::Printer* printer) const override;
void GenerateKotlinDslMembers(io::Printer* printer) const override;
std::string GetBoxedType() const override;
private:
const FieldDescriptor* descriptor_;

@ -63,20 +63,20 @@ class ImmutableStringFieldLiteGenerator : public ImmutableFieldLiteGenerator {
explicit ImmutableStringFieldLiteGenerator(const FieldDescriptor* descriptor,
int messageBitIndex,
Context* context);
~ImmutableStringFieldLiteGenerator();
~ImmutableStringFieldLiteGenerator() override;
// implements ImmutableFieldLiteGenerator
// ------------------------------------
int GetNumBitsForMessage() const;
void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
int GetNumBitsForMessage() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
void GenerateMembers(io::Printer* printer) const override;
void GenerateBuilderMembers(io::Printer* printer) const override;
void GenerateInitializationCode(io::Printer* printer) const override;
void GenerateFieldInfo(io::Printer* printer,
std::vector<uint16_t>* output) const;
void GenerateKotlinDslMembers(io::Printer* printer) const;
std::vector<uint16_t>* output) const override;
void GenerateKotlinDslMembers(io::Printer* printer) const override;
std::string GetBoxedType() const;
std::string GetBoxedType() const override;
protected:
const FieldDescriptor* descriptor_;
@ -93,13 +93,13 @@ class ImmutableStringOneofFieldLiteGenerator
public:
ImmutableStringOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
int messageBitIndex, Context* context);
~ImmutableStringOneofFieldLiteGenerator();
~ImmutableStringOneofFieldLiteGenerator() override;
private:
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const override;
void GenerateBuilderMembers(io::Printer* printer) const override;
void GenerateFieldInfo(io::Printer* printer,
std::vector<uint16_t>* output) const;
std::vector<uint16_t>* output) const override;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringOneofFieldLiteGenerator);
};
@ -109,19 +109,19 @@ class RepeatedImmutableStringFieldLiteGenerator
public:
explicit RepeatedImmutableStringFieldLiteGenerator(
const FieldDescriptor* descriptor, int messageBitIndex, Context* context);
~RepeatedImmutableStringFieldLiteGenerator();
~RepeatedImmutableStringFieldLiteGenerator() override;
// implements ImmutableFieldLiteGenerator ------------------------------------
int GetNumBitsForMessage() const;
void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
int GetNumBitsForMessage() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
void GenerateMembers(io::Printer* printer) const override;
void GenerateBuilderMembers(io::Printer* printer) const override;
void GenerateInitializationCode(io::Printer* printer) const override;
void GenerateFieldInfo(io::Printer* printer,
std::vector<uint16_t>* output) const;
void GenerateKotlinDslMembers(io::Printer* printer) const;
std::vector<uint16_t>* output) const override;
void GenerateKotlinDslMembers(io::Printer* printer) const override;
std::string GetBoxedType() const;
std::string GetBoxedType() const override;
private:
const FieldDescriptor* descriptor_;

@ -230,10 +230,13 @@ class Version::_Internal {
}
};
Version::Version(::PROTOBUF_NAMESPACE_ID::Arena* arena)
: ::PROTOBUF_NAMESPACE_ID::Message(arena) {
Version::Version(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned)
: ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
SharedCtor();
RegisterArenaDtor(arena);
if (!is_message_owned) {
RegisterArenaDtor(arena);
}
// @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.Version)
}
Version::Version(const Version& from)
@ -251,7 +254,7 @@ Version::Version(const Version& from)
// @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.Version)
}
void Version::SharedCtor() {
inline void Version::SharedCtor() {
suffix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
reinterpret_cast<char*>(&major_) - reinterpret_cast<char*>(this)),
@ -261,11 +264,12 @@ suffix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlrea
Version::~Version() {
// @@protoc_insertion_point(destructor:google.protobuf.compiler.Version)
if (GetArenaForAllocation() != nullptr) return;
SharedDtor();
_internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}
void Version::SharedDtor() {
inline void Version::SharedDtor() {
GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
suffix_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
}
@ -456,25 +460,22 @@ size_t Version::ByteSizeLong() const {
return total_size;
}
void Version::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.Version)
GOOGLE_DCHECK_NE(&from, this);
const Version* source =
::PROTOBUF_NAMESPACE_ID::DynamicCastToGenerated<Version>(
&from);
if (source == nullptr) {
// @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.Version)
::PROTOBUF_NAMESPACE_ID::internal::ReflectionOps::Merge(from, this);
} else {
// @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.compiler.Version)
MergeFrom(*source);
}
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Version::_class_data_ = {
::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
Version::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Version::GetClassData() const { return &_class_data_; }
void Version::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to,
const ::PROTOBUF_NAMESPACE_ID::Message&from) {
static_cast<Version *>(to)->MergeFrom(
static_cast<const Version &>(from));
}
void Version::MergeFrom(const Version& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.Version)
GOOGLE_DCHECK_NE(&from, this);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
(void) cached_has_bits;
@ -494,13 +495,7 @@ void Version::MergeFrom(const Version& from) {
}
_has_bits_[0] |= cached_has_bits;
}
}
void Version::CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.compiler.Version)
if (&from == this) return;
Clear();
MergeFrom(from);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}
void Version::CopyFrom(const Version& from) {
@ -558,12 +553,15 @@ CodeGeneratorRequest::_Internal::compiler_version(const CodeGeneratorRequest* ms
void CodeGeneratorRequest::clear_proto_file() {
proto_file_.Clear();
}
CodeGeneratorRequest::CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena)
: ::PROTOBUF_NAMESPACE_ID::Message(arena),
CodeGeneratorRequest::CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned)
: ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
file_to_generate_(arena),
proto_file_(arena) {
SharedCtor();
RegisterArenaDtor(arena);
if (!is_message_owned) {
RegisterArenaDtor(arena);
}
// @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorRequest)
}
CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from)
@ -585,18 +583,19 @@ CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from)
// @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorRequest)
}
void CodeGeneratorRequest::SharedCtor() {
inline void CodeGeneratorRequest::SharedCtor() {
parameter_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
compiler_version_ = nullptr;
}
CodeGeneratorRequest::~CodeGeneratorRequest() {
// @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorRequest)
if (GetArenaForAllocation() != nullptr) return;
SharedDtor();
_internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}
void CodeGeneratorRequest::SharedDtor() {
inline void CodeGeneratorRequest::SharedDtor() {
GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
parameter_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
if (this != internal_default_instance()) delete compiler_version_;
@ -811,25 +810,22 @@ size_t CodeGeneratorRequest::ByteSizeLong() const {
return total_size;
}
void CodeGeneratorRequest::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.CodeGeneratorRequest)
GOOGLE_DCHECK_NE(&from, this);
const CodeGeneratorRequest* source =
::PROTOBUF_NAMESPACE_ID::DynamicCastToGenerated<CodeGeneratorRequest>(
&from);
if (source == nullptr) {
// @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.CodeGeneratorRequest)
::PROTOBUF_NAMESPACE_ID::internal::ReflectionOps::Merge(from, this);
} else {
// @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.compiler.CodeGeneratorRequest)
MergeFrom(*source);
}
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData CodeGeneratorRequest::_class_data_ = {
::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
CodeGeneratorRequest::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*CodeGeneratorRequest::GetClassData() const { return &_class_data_; }
void CodeGeneratorRequest::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to,
const ::PROTOBUF_NAMESPACE_ID::Message&from) {
static_cast<CodeGeneratorRequest *>(to)->MergeFrom(
static_cast<const CodeGeneratorRequest &>(from));
}
void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorRequest)
GOOGLE_DCHECK_NE(&from, this);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
(void) cached_has_bits;
@ -844,13 +840,7 @@ void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) {
_internal_mutable_compiler_version()->PROTOBUF_NAMESPACE_ID::compiler::Version::MergeFrom(from._internal_compiler_version());
}
}
}
void CodeGeneratorRequest::CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.compiler.CodeGeneratorRequest)
if (&from == this) return;
Clear();
MergeFrom(from);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}
void CodeGeneratorRequest::CopyFrom(const CodeGeneratorRequest& from) {
@ -913,10 +903,13 @@ void CodeGeneratorResponse_File::clear_generated_code_info() {
if (generated_code_info_ != nullptr) generated_code_info_->Clear();
_has_bits_[0] &= ~0x00000008u;
}
CodeGeneratorResponse_File::CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::Arena* arena)
: ::PROTOBUF_NAMESPACE_ID::Message(arena) {
CodeGeneratorResponse_File::CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned)
: ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
SharedCtor();
RegisterArenaDtor(arena);
if (!is_message_owned) {
RegisterArenaDtor(arena);
}
// @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorResponse.File)
}
CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from)
@ -946,7 +939,7 @@ CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorRespon
// @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse.File)
}
void CodeGeneratorResponse_File::SharedCtor() {
inline void CodeGeneratorResponse_File::SharedCtor() {
name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
insertion_point_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
content_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
@ -955,11 +948,12 @@ generated_code_info_ = nullptr;
CodeGeneratorResponse_File::~CodeGeneratorResponse_File() {
// @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse.File)
if (GetArenaForAllocation() != nullptr) return;
SharedDtor();
_internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}
void CodeGeneratorResponse_File::SharedDtor() {
inline void CodeGeneratorResponse_File::SharedDtor() {
GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
insertion_point_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
@ -1175,25 +1169,22 @@ size_t CodeGeneratorResponse_File::ByteSizeLong() const {
return total_size;
}
void CodeGeneratorResponse_File::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse.File)
GOOGLE_DCHECK_NE(&from, this);
const CodeGeneratorResponse_File* source =
::PROTOBUF_NAMESPACE_ID::DynamicCastToGenerated<CodeGeneratorResponse_File>(
&from);
if (source == nullptr) {
// @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.CodeGeneratorResponse.File)
::PROTOBUF_NAMESPACE_ID::internal::ReflectionOps::Merge(from, this);
} else {
// @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.compiler.CodeGeneratorResponse.File)
MergeFrom(*source);
}
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData CodeGeneratorResponse_File::_class_data_ = {
::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
CodeGeneratorResponse_File::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*CodeGeneratorResponse_File::GetClassData() const { return &_class_data_; }
void CodeGeneratorResponse_File::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to,
const ::PROTOBUF_NAMESPACE_ID::Message&from) {
static_cast<CodeGeneratorResponse_File *>(to)->MergeFrom(
static_cast<const CodeGeneratorResponse_File &>(from));
}
void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse.File)
GOOGLE_DCHECK_NE(&from, this);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
(void) cached_has_bits;
@ -1212,13 +1203,7 @@ void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& fro
_internal_mutable_generated_code_info()->PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo::MergeFrom(from._internal_generated_code_info());
}
}
}
void CodeGeneratorResponse_File::CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.compiler.CodeGeneratorResponse.File)
if (&from == this) return;
Clear();
MergeFrom(from);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}
void CodeGeneratorResponse_File::CopyFrom(const CodeGeneratorResponse_File& from) {
@ -1273,11 +1258,14 @@ class CodeGeneratorResponse::_Internal {
}
};
CodeGeneratorResponse::CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::Arena* arena)
: ::PROTOBUF_NAMESPACE_ID::Message(arena),
CodeGeneratorResponse::CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned)
: ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
file_(arena) {
SharedCtor();
RegisterArenaDtor(arena);
if (!is_message_owned) {
RegisterArenaDtor(arena);
}
// @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorResponse)
}
CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from)
@ -1294,18 +1282,19 @@ CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from)
// @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse)
}
void CodeGeneratorResponse::SharedCtor() {
inline void CodeGeneratorResponse::SharedCtor() {
error_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
supported_features_ = uint64_t{0u};
}
CodeGeneratorResponse::~CodeGeneratorResponse() {
// @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse)
if (GetArenaForAllocation() != nullptr) return;
SharedDtor();
_internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}
void CodeGeneratorResponse::SharedDtor() {
inline void CodeGeneratorResponse::SharedDtor() {
GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
error_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
}
@ -1478,25 +1467,22 @@ size_t CodeGeneratorResponse::ByteSizeLong() const {
return total_size;
}
void CodeGeneratorResponse::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse)
GOOGLE_DCHECK_NE(&from, this);
const CodeGeneratorResponse* source =
::PROTOBUF_NAMESPACE_ID::DynamicCastToGenerated<CodeGeneratorResponse>(
&from);
if (source == nullptr) {
// @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.CodeGeneratorResponse)
::PROTOBUF_NAMESPACE_ID::internal::ReflectionOps::Merge(from, this);
} else {
// @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.compiler.CodeGeneratorResponse)
MergeFrom(*source);
}
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData CodeGeneratorResponse::_class_data_ = {
::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
CodeGeneratorResponse::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*CodeGeneratorResponse::GetClassData() const { return &_class_data_; }
void CodeGeneratorResponse::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to,
const ::PROTOBUF_NAMESPACE_ID::Message&from) {
static_cast<CodeGeneratorResponse *>(to)->MergeFrom(
static_cast<const CodeGeneratorResponse &>(from));
}
void CodeGeneratorResponse::MergeFrom(const CodeGeneratorResponse& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse)
GOOGLE_DCHECK_NE(&from, this);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
(void) cached_has_bits;
@ -1511,13 +1497,7 @@ void CodeGeneratorResponse::MergeFrom(const CodeGeneratorResponse& from) {
}
_has_bits_[0] |= cached_has_bits;
}
}
void CodeGeneratorResponse::CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.compiler.CodeGeneratorResponse)
if (&from == this) return;
Clear();
MergeFrom(from);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}
void CodeGeneratorResponse::CopyFrom(const CodeGeneratorResponse& from) {

@ -190,10 +190,13 @@ class PROTOC_EXPORT Version final :
Version* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
return CreateMaybeMessage<Version>(arena);
}
void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
void CopyFrom(const Version& from);
using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
void MergeFrom(const Version& from);
private:
static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from);
public:
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
bool IsInitialized() const final;
@ -213,12 +216,16 @@ class PROTOC_EXPORT Version final :
return "google.protobuf.compiler.Version";
}
protected:
explicit Version(::PROTOBUF_NAMESPACE_ID::Arena* arena);
explicit Version(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned = false);
private:
static void ArenaDtor(void* object);
inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
public:
static const ClassData _class_data_;
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
// nested types ----------------------------------------------------
@ -241,7 +248,7 @@ class PROTOC_EXPORT Version final :
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_suffix(ArgT0&& arg0, ArgT... args);
std::string* mutable_suffix();
PROTOBUF_FUTURE_MUST_USE_RESULT std::string* release_suffix();
PROTOBUF_MUST_USE_RESULT std::string* release_suffix();
void set_allocated_suffix(std::string* suffix);
private:
const std::string& _internal_suffix() const;
@ -384,10 +391,13 @@ class PROTOC_EXPORT CodeGeneratorRequest final :
CodeGeneratorRequest* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
return CreateMaybeMessage<CodeGeneratorRequest>(arena);
}
void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
void CopyFrom(const CodeGeneratorRequest& from);
using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
void MergeFrom(const CodeGeneratorRequest& from);
private:
static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from);
public:
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
bool IsInitialized() const final;
@ -407,12 +417,16 @@ class PROTOC_EXPORT CodeGeneratorRequest final :
return "google.protobuf.compiler.CodeGeneratorRequest";
}
protected:
explicit CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena);
explicit CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned = false);
private:
static void ArenaDtor(void* object);
inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
public:
static const ClassData _class_data_;
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
// nested types ----------------------------------------------------
@ -477,7 +491,7 @@ class PROTOC_EXPORT CodeGeneratorRequest final :
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_parameter(ArgT0&& arg0, ArgT... args);
std::string* mutable_parameter();
PROTOBUF_FUTURE_MUST_USE_RESULT std::string* release_parameter();
PROTOBUF_MUST_USE_RESULT std::string* release_parameter();
void set_allocated_parameter(std::string* parameter);
private:
const std::string& _internal_parameter() const;
@ -492,7 +506,7 @@ class PROTOC_EXPORT CodeGeneratorRequest final :
public:
void clear_compiler_version();
const PROTOBUF_NAMESPACE_ID::compiler::Version& compiler_version() const;
PROTOBUF_FUTURE_MUST_USE_RESULT PROTOBUF_NAMESPACE_ID::compiler::Version* release_compiler_version();
PROTOBUF_MUST_USE_RESULT PROTOBUF_NAMESPACE_ID::compiler::Version* release_compiler_version();
PROTOBUF_NAMESPACE_ID::compiler::Version* mutable_compiler_version();
void set_allocated_compiler_version(PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version);
private:
@ -599,10 +613,13 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final :
CodeGeneratorResponse_File* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
return CreateMaybeMessage<CodeGeneratorResponse_File>(arena);
}
void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
void CopyFrom(const CodeGeneratorResponse_File& from);
using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
void MergeFrom(const CodeGeneratorResponse_File& from);
private:
static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from);
public:
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
bool IsInitialized() const final;
@ -622,12 +639,16 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final :
return "google.protobuf.compiler.CodeGeneratorResponse.File";
}
protected:
explicit CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::Arena* arena);
explicit CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned = false);
private:
static void ArenaDtor(void* object);
inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
public:
static const ClassData _class_data_;
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
// nested types ----------------------------------------------------
@ -650,7 +671,7 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final :
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_name(ArgT0&& arg0, ArgT... args);
std::string* mutable_name();
PROTOBUF_FUTURE_MUST_USE_RESULT std::string* release_name();
PROTOBUF_MUST_USE_RESULT std::string* release_name();
void set_allocated_name(std::string* name);
private:
const std::string& _internal_name() const;
@ -668,7 +689,7 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final :
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_insertion_point(ArgT0&& arg0, ArgT... args);
std::string* mutable_insertion_point();
PROTOBUF_FUTURE_MUST_USE_RESULT std::string* release_insertion_point();
PROTOBUF_MUST_USE_RESULT std::string* release_insertion_point();
void set_allocated_insertion_point(std::string* insertion_point);
private:
const std::string& _internal_insertion_point() const;
@ -686,7 +707,7 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final :
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_content(ArgT0&& arg0, ArgT... args);
std::string* mutable_content();
PROTOBUF_FUTURE_MUST_USE_RESULT std::string* release_content();
PROTOBUF_MUST_USE_RESULT std::string* release_content();
void set_allocated_content(std::string* content);
private:
const std::string& _internal_content() const;
@ -701,7 +722,7 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final :
public:
void clear_generated_code_info();
const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& generated_code_info() const;
PROTOBUF_FUTURE_MUST_USE_RESULT PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* release_generated_code_info();
PROTOBUF_MUST_USE_RESULT PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* release_generated_code_info();
PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* mutable_generated_code_info();
void set_allocated_generated_code_info(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info);
private:
@ -808,10 +829,13 @@ class PROTOC_EXPORT CodeGeneratorResponse final :
CodeGeneratorResponse* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
return CreateMaybeMessage<CodeGeneratorResponse>(arena);
}
void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
void CopyFrom(const CodeGeneratorResponse& from);
using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
void MergeFrom(const CodeGeneratorResponse& from);
private:
static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from);
public:
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
bool IsInitialized() const final;
@ -831,12 +855,16 @@ class PROTOC_EXPORT CodeGeneratorResponse final :
return "google.protobuf.compiler.CodeGeneratorResponse";
}
protected:
explicit CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::Arena* arena);
explicit CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned = false);
private:
static void ArenaDtor(void* object);
inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
public:
static const ClassData _class_data_;
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
// nested types ----------------------------------------------------
@ -908,7 +936,7 @@ class PROTOC_EXPORT CodeGeneratorResponse final :
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_error(ArgT0&& arg0, ArgT... args);
std::string* mutable_error();
PROTOBUF_FUTURE_MUST_USE_RESULT std::string* release_error();
PROTOBUF_MUST_USE_RESULT std::string* release_error();
void set_allocated_error(std::string* error);
private:
const std::string& _internal_error() const;
@ -1062,8 +1090,9 @@ void Version::set_suffix(ArgT0&& arg0, ArgT... args) {
// @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.suffix)
}
inline std::string* Version::mutable_suffix() {
std::string* _s = _internal_mutable_suffix();
// @@protoc_insertion_point(field_mutable:google.protobuf.compiler.Version.suffix)
return _internal_mutable_suffix();
return _s;
}
inline const std::string& Version::_internal_suffix() const {
return suffix_.Get();
@ -1110,8 +1139,9 @@ inline void CodeGeneratorRequest::clear_file_to_generate() {
file_to_generate_.Clear();
}
inline std::string* CodeGeneratorRequest::add_file_to_generate() {
std::string* _s = _internal_add_file_to_generate();
// @@protoc_insertion_point(field_add_mutable:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
return _internal_add_file_to_generate();
return _s;
}
inline const std::string& CodeGeneratorRequest::_internal_file_to_generate(int index) const {
return file_to_generate_.Get(index);
@ -1125,12 +1155,12 @@ inline std::string* CodeGeneratorRequest::mutable_file_to_generate(int index) {
return file_to_generate_.Mutable(index);
}
inline void CodeGeneratorRequest::set_file_to_generate(int index, const std::string& value) {
// @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
file_to_generate_.Mutable(index)->assign(value);
// @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
}
inline void CodeGeneratorRequest::set_file_to_generate(int index, std::string&& value) {
// @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
file_to_generate_.Mutable(index)->assign(std::move(value));
// @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
}
inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value) {
GOOGLE_DCHECK(value != nullptr);
@ -1197,8 +1227,9 @@ void CodeGeneratorRequest::set_parameter(ArgT0&& arg0, ArgT... args) {
// @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.parameter)
}
inline std::string* CodeGeneratorRequest::mutable_parameter() {
std::string* _s = _internal_mutable_parameter();
// @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.parameter)
return _internal_mutable_parameter();
return _s;
}
inline const std::string& CodeGeneratorRequest::_internal_parameter() const {
return parameter_.Get();
@ -1257,8 +1288,9 @@ inline PROTOBUF_NAMESPACE_ID::FileDescriptorProto* CodeGeneratorRequest::_intern
return proto_file_.Add();
}
inline PROTOBUF_NAMESPACE_ID::FileDescriptorProto* CodeGeneratorRequest::add_proto_file() {
PROTOBUF_NAMESPACE_ID::FileDescriptorProto* _add = _internal_add_proto_file();
// @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
return _internal_add_proto_file();
return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::FileDescriptorProto >&
CodeGeneratorRequest::proto_file() const {
@ -1326,8 +1358,9 @@ inline PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::_internal
return compiler_version_;
}
inline PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::mutable_compiler_version() {
PROTOBUF_NAMESPACE_ID::compiler::Version* _msg = _internal_mutable_compiler_version();
// @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
return _internal_mutable_compiler_version();
return _msg;
}
inline void CodeGeneratorRequest::set_allocated_compiler_version(PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version) {
::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
@ -1377,8 +1410,9 @@ void CodeGeneratorResponse_File::set_name(ArgT0&& arg0, ArgT... args) {
// @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.name)
}
inline std::string* CodeGeneratorResponse_File::mutable_name() {
std::string* _s = _internal_mutable_name();
// @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.name)
return _internal_mutable_name();
return _s;
}
inline const std::string& CodeGeneratorResponse_File::_internal_name() const {
return name_.Get();
@ -1434,8 +1468,9 @@ void CodeGeneratorResponse_File::set_insertion_point(ArgT0&& arg0, ArgT... args)
// @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
}
inline std::string* CodeGeneratorResponse_File::mutable_insertion_point() {
std::string* _s = _internal_mutable_insertion_point();
// @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
return _internal_mutable_insertion_point();
return _s;
}
inline const std::string& CodeGeneratorResponse_File::_internal_insertion_point() const {
return insertion_point_.Get();
@ -1491,8 +1526,9 @@ void CodeGeneratorResponse_File::set_content(ArgT0&& arg0, ArgT... args) {
// @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.content)
}
inline std::string* CodeGeneratorResponse_File::mutable_content() {
std::string* _s = _internal_mutable_content();
// @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.content)
return _internal_mutable_content();
return _s;
}
inline const std::string& CodeGeneratorResponse_File::_internal_content() const {
return content_.Get();
@ -1580,8 +1616,9 @@ inline PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::_in
return generated_code_info_;
}
inline PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::mutable_generated_code_info() {
PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* _msg = _internal_mutable_generated_code_info();
// @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info)
return _internal_mutable_generated_code_info();
return _msg;
}
inline void CodeGeneratorResponse_File::set_allocated_generated_code_info(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info) {
::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
@ -1633,8 +1670,9 @@ void CodeGeneratorResponse::set_error(ArgT0&& arg0, ArgT... args) {
// @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.error)
}
inline std::string* CodeGeneratorResponse::mutable_error() {
std::string* _s = _internal_mutable_error();
// @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.error)
return _internal_mutable_error();
return _s;
}
inline const std::string& CodeGeneratorResponse::_internal_error() const {
return error_.Get();
@ -1724,8 +1762,9 @@ inline PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* CodeGenerato
return file_.Add();
}
inline PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::add_file() {
PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* _add = _internal_add_file();
// @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorResponse.file)
return _internal_add_file();
return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >&
CodeGeneratorResponse::file() const {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -81,10 +81,13 @@ class Duration::_Internal {
public:
};
Duration::Duration(::PROTOBUF_NAMESPACE_ID::Arena* arena)
: ::PROTOBUF_NAMESPACE_ID::Message(arena) {
Duration::Duration(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned)
: ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
SharedCtor();
RegisterArenaDtor(arena);
if (!is_message_owned) {
RegisterArenaDtor(arena);
}
// @@protoc_insertion_point(arena_constructor:google.protobuf.Duration)
}
Duration::Duration(const Duration& from)
@ -96,7 +99,7 @@ Duration::Duration(const Duration& from)
// @@protoc_insertion_point(copy_constructor:google.protobuf.Duration)
}
void Duration::SharedCtor() {
inline void Duration::SharedCtor() {
::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
reinterpret_cast<char*>(&seconds_) - reinterpret_cast<char*>(this)),
0, static_cast<size_t>(reinterpret_cast<char*>(&nanos_) -
@ -105,11 +108,12 @@ void Duration::SharedCtor() {
Duration::~Duration() {
// @@protoc_insertion_point(destructor:google.protobuf.Duration)
if (GetArenaForAllocation() != nullptr) return;
SharedDtor();
_internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}
void Duration::SharedDtor() {
inline void Duration::SharedDtor() {
GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
}
@ -235,25 +239,22 @@ size_t Duration::ByteSizeLong() const {
return total_size;
}
void Duration::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Duration)
GOOGLE_DCHECK_NE(&from, this);
const Duration* source =
::PROTOBUF_NAMESPACE_ID::DynamicCastToGenerated<Duration>(
&from);
if (source == nullptr) {
// @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Duration)
::PROTOBUF_NAMESPACE_ID::internal::ReflectionOps::Merge(from, this);
} else {
// @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Duration)
MergeFrom(*source);
}
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Duration::_class_data_ = {
::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
Duration::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Duration::GetClassData() const { return &_class_data_; }
void Duration::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to,
const ::PROTOBUF_NAMESPACE_ID::Message&from) {
static_cast<Duration *>(to)->MergeFrom(
static_cast<const Duration &>(from));
}
void Duration::MergeFrom(const Duration& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Duration)
GOOGLE_DCHECK_NE(&from, this);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
(void) cached_has_bits;
@ -263,13 +264,7 @@ void Duration::MergeFrom(const Duration& from) {
if (from.nanos() != 0) {
_internal_set_nanos(from._internal_nanos());
}
}
void Duration::CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Duration)
if (&from == this) return;
Clear();
MergeFrom(from);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}
void Duration::CopyFrom(const Duration& from) {

@ -137,10 +137,13 @@ class PROTOBUF_EXPORT Duration final :
Duration* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
return CreateMaybeMessage<Duration>(arena);
}
void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
void CopyFrom(const Duration& from);
using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
void MergeFrom(const Duration& from);
private:
static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from);
public:
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
bool IsInitialized() const final;
@ -160,12 +163,16 @@ class PROTOBUF_EXPORT Duration final :
return "google.protobuf.Duration";
}
protected:
explicit Duration(::PROTOBUF_NAMESPACE_ID::Arena* arena);
explicit Duration(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned = false);
private:
static void ArenaDtor(void* object);
inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
public:
static const ClassData _class_data_;
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
// nested types ----------------------------------------------------

@ -76,10 +76,13 @@ class Empty::_Internal {
public:
};
Empty::Empty(::PROTOBUF_NAMESPACE_ID::Arena* arena)
: ::PROTOBUF_NAMESPACE_ID::Message(arena) {
Empty::Empty(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned)
: ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
SharedCtor();
RegisterArenaDtor(arena);
if (!is_message_owned) {
RegisterArenaDtor(arena);
}
// @@protoc_insertion_point(arena_constructor:google.protobuf.Empty)
}
Empty::Empty(const Empty& from)
@ -88,16 +91,17 @@ Empty::Empty(const Empty& from)
// @@protoc_insertion_point(copy_constructor:google.protobuf.Empty)
}
void Empty::SharedCtor() {
inline void Empty::SharedCtor() {
}
Empty::~Empty() {
// @@protoc_insertion_point(destructor:google.protobuf.Empty)
if (GetArenaForAllocation() != nullptr) return;
SharedDtor();
_internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}
void Empty::SharedDtor() {
inline void Empty::SharedDtor() {
GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
}
@ -175,35 +179,26 @@ size_t Empty::ByteSizeLong() const {
return total_size;
}
void Empty::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Empty)
GOOGLE_DCHECK_NE(&from, this);
const Empty* source =
::PROTOBUF_NAMESPACE_ID::DynamicCastToGenerated<Empty>(
&from);
if (source == nullptr) {
// @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Empty)
::PROTOBUF_NAMESPACE_ID::internal::ReflectionOps::Merge(from, this);
} else {
// @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Empty)
MergeFrom(*source);
}
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Empty::_class_data_ = {
::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
Empty::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Empty::GetClassData() const { return &_class_data_; }
void Empty::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to,
const ::PROTOBUF_NAMESPACE_ID::Message&from) {
static_cast<Empty *>(to)->MergeFrom(
static_cast<const Empty &>(from));
}
void Empty::MergeFrom(const Empty& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Empty)
GOOGLE_DCHECK_NE(&from, this);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
(void) cached_has_bits;
}
void Empty::CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Empty)
if (&from == this) return;
Clear();
MergeFrom(from);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}
void Empty::CopyFrom(const Empty& from) {

@ -137,10 +137,13 @@ class PROTOBUF_EXPORT Empty final :
Empty* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
return CreateMaybeMessage<Empty>(arena);
}
void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
void CopyFrom(const Empty& from);
using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
void MergeFrom(const Empty& from);
private:
static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from);
public:
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
bool IsInitialized() const final;
@ -160,12 +163,16 @@ class PROTOBUF_EXPORT Empty final :
return "google.protobuf.Empty";
}
protected:
explicit Empty(::PROTOBUF_NAMESPACE_ID::Arena* arena);
explicit Empty(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned = false);
private:
static void ArenaDtor(void* object);
inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
public:
static const ClassData _class_data_;
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
// nested types ----------------------------------------------------

@ -616,6 +616,10 @@ void ExtensionSet::SetAllocatedMessage(int number, FieldType type,
ClearExtension(number);
return;
}
#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT
GOOGLE_DCHECK(message->GetOwningArena() == nullptr ||
message->GetOwningArena() == arena_);
#endif // PROTOBUF_INTERNAL_USE_MUST_USE_RESULT
Arena* message_arena = message->GetOwningArena();
Extension* extension;
if (MaybeNewExtension(number, descriptor, &extension)) {
@ -1054,7 +1058,11 @@ void ExtensionSet::InternalExtensionMergeFrom(
}
void ExtensionSet::Swap(ExtensionSet* x) {
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
if (GetArena() != nullptr && GetArena() == x->GetArena()) {
#else // PROTOBUF_FORCE_COPY_IN_SWAP
if (GetArena() == x->GetArena()) {
#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
InternalSwap(x);
} else {
// TODO(cfallin, rohananil): We maybe able to optimize a case where we are
@ -1079,52 +1087,59 @@ void ExtensionSet::InternalSwap(ExtensionSet* other) {
void ExtensionSet::SwapExtension(ExtensionSet* other, int number) {
if (this == other) return;
Extension* this_ext = FindOrNull(number);
Extension* other_ext = other->FindOrNull(number);
if (this_ext == NULL && other_ext == NULL) {
if (GetArena() == other->GetArena()) {
UnsafeShallowSwapExtension(other, number);
return;
}
if (this_ext != NULL && other_ext != NULL) {
if (GetArena() == other->GetArena()) {
using std::swap;
swap(*this_ext, *other_ext);
} else {
// TODO(cfallin, rohananil): We could further optimize these cases,
// especially avoid creation of ExtensionSet, and move MergeFrom logic
// into Extensions itself (which takes arena as an argument).
// We do it this way to reuse the copy-across-arenas logic already
// implemented in ExtensionSet's MergeFrom.
ExtensionSet temp;
temp.InternalExtensionMergeFrom(number, *other_ext);
Extension* temp_ext = temp.FindOrNull(number);
other_ext->Clear();
other->InternalExtensionMergeFrom(number, *this_ext);
this_ext->Clear();
InternalExtensionMergeFrom(number, *temp_ext);
}
return;
}
Extension* this_ext = FindOrNull(number);
Extension* other_ext = other->FindOrNull(number);
if (this_ext == NULL) {
if (GetArena() == other->GetArena()) {
*Insert(number).first = *other_ext;
} else {
InternalExtensionMergeFrom(number, *other_ext);
}
if (this_ext == other_ext) return;
if (this_ext != nullptr && other_ext != nullptr) {
// TODO(cfallin, rohananil): We could further optimize these cases,
// especially avoid creation of ExtensionSet, and move MergeFrom logic
// into Extensions itself (which takes arena as an argument).
// We do it this way to reuse the copy-across-arenas logic already
// implemented in ExtensionSet's MergeFrom.
ExtensionSet temp;
temp.InternalExtensionMergeFrom(number, *other_ext);
Extension* temp_ext = temp.FindOrNull(number);
other_ext->Clear();
other->InternalExtensionMergeFrom(number, *this_ext);
this_ext->Clear();
InternalExtensionMergeFrom(number, *temp_ext);
} else if (this_ext == nullptr) {
InternalExtensionMergeFrom(number, *other_ext);
if (other->GetArena() == nullptr) other_ext->Free();
other->Erase(number);
return;
} else {
other->InternalExtensionMergeFrom(number, *this_ext);
if (GetArena() == nullptr) this_ext->Free();
Erase(number);
}
}
if (other_ext == NULL) {
if (GetArena() == other->GetArena()) {
*other->Insert(number).first = *this_ext;
} else {
other->InternalExtensionMergeFrom(number, *this_ext);
}
void ExtensionSet::UnsafeShallowSwapExtension(ExtensionSet* other, int number) {
if (this == other) return;
Extension* this_ext = FindOrNull(number);
Extension* other_ext = other->FindOrNull(number);
if (this_ext == other_ext) return;
GOOGLE_DCHECK_EQ(GetArena(), other->GetArena());
if (this_ext != nullptr && other_ext != nullptr) {
std::swap(*this_ext, *other_ext);
} else if (this_ext == nullptr) {
*Insert(number).first = *other_ext;
other->Erase(number);
} else {
*other->Insert(number).first = *this_ext;
Erase(number);
return;
}
}
@ -1725,7 +1740,7 @@ int ExtensionSet::Extension::GetSize() const {
}
// This function deletes all allocated objects. This function should be only
// called if the Extension was created with an arena.
// called if the Extension was created without an arena.
void ExtensionSet::Extension::Free() {
if (is_repeated) {
switch (cpp_type(type)) {

@ -282,12 +282,12 @@ class PROTOBUF_EXPORT ExtensionSet {
void UnsafeArenaSetAllocatedMessage(int number, FieldType type,
const FieldDescriptor* descriptor,
MessageLite* message);
PROTOBUF_FUTURE_MUST_USE_RESULT MessageLite* ReleaseMessage(
PROTOBUF_MUST_USE_RESULT MessageLite* ReleaseMessage(
int number, const MessageLite& prototype);
MessageLite* UnsafeArenaReleaseMessage(int number,
const MessageLite& prototype);
PROTOBUF_FUTURE_MUST_USE_RESULT MessageLite* ReleaseMessage(
PROTOBUF_MUST_USE_RESULT MessageLite* ReleaseMessage(
const FieldDescriptor* descriptor, MessageFactory* factory);
MessageLite* UnsafeArenaReleaseMessage(const FieldDescriptor* descriptor,
MessageFactory* factory);
@ -355,7 +355,7 @@ class PROTOBUF_EXPORT ExtensionSet {
#undef desc
void RemoveLast(int number);
PROTOBUF_FUTURE_MUST_USE_RESULT MessageLite* ReleaseLast(int number);
PROTOBUF_MUST_USE_RESULT MessageLite* ReleaseLast(int number);
void SwapElements(int number, int index1, int index2);
// -----------------------------------------------------------------
@ -372,6 +372,7 @@ class PROTOBUF_EXPORT ExtensionSet {
void Swap(ExtensionSet* other);
void InternalSwap(ExtensionSet* other);
void SwapExtension(ExtensionSet* other, int number);
void UnsafeShallowSwapExtension(ExtensionSet* other, int number);
bool IsInitialized() const;
// Parses a single extension from the input. The input should start out
@ -535,7 +536,7 @@ class PROTOBUF_EXPORT ExtensionSet {
virtual MessageLite* MutableMessage(const MessageLite& prototype) = 0;
virtual void SetAllocatedMessage(MessageLite* message) = 0;
virtual void UnsafeArenaSetAllocatedMessage(MessageLite* message) = 0;
virtual PROTOBUF_FUTURE_MUST_USE_RESULT MessageLite* ReleaseMessage(
virtual PROTOBUF_MUST_USE_RESULT MessageLite* ReleaseMessage(
const MessageLite& prototype) = 0;
virtual MessageLite* UnsafeArenaReleaseMessage(
const MessageLite& prototype) = 0;
@ -1262,7 +1263,7 @@ class MessageTypeTraits {
ExtensionSet* set) {
set->UnsafeArenaSetAllocatedMessage(number, field_type, NULL, message);
}
static inline PROTOBUF_FUTURE_MUST_USE_RESULT MutableType
static inline PROTOBUF_MUST_USE_RESULT MutableType
Release(int number, FieldType /* field_type */, ExtensionSet* set) {
return static_cast<Type*>(
set->ReleaseMessage(number, Type::default_instance()));
@ -1478,7 +1479,7 @@ class ExtensionIdentifier {
template <typename _proto_TypeTraits, \
::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \
bool _is_packed> \
inline PROTOBUF_FUTURE_MUST_USE_RESULT \
inline PROTOBUF_MUST_USE_RESULT \
typename _proto_TypeTraits::Singular::MutableType \
ReleaseExtension( \
const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< \

@ -79,11 +79,14 @@ class FieldMask::_Internal {
public:
};
FieldMask::FieldMask(::PROTOBUF_NAMESPACE_ID::Arena* arena)
: ::PROTOBUF_NAMESPACE_ID::Message(arena),
FieldMask::FieldMask(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned)
: ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
paths_(arena) {
SharedCtor();
RegisterArenaDtor(arena);
if (!is_message_owned) {
RegisterArenaDtor(arena);
}
// @@protoc_insertion_point(arena_constructor:google.protobuf.FieldMask)
}
FieldMask::FieldMask(const FieldMask& from)
@ -93,16 +96,17 @@ FieldMask::FieldMask(const FieldMask& from)
// @@protoc_insertion_point(copy_constructor:google.protobuf.FieldMask)
}
void FieldMask::SharedCtor() {
inline void FieldMask::SharedCtor() {
}
FieldMask::~FieldMask() {
// @@protoc_insertion_point(destructor:google.protobuf.FieldMask)
if (GetArenaForAllocation() != nullptr) return;
SharedDtor();
_internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}
void FieldMask::SharedDtor() {
inline void FieldMask::SharedDtor() {
GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
}
@ -218,36 +222,27 @@ size_t FieldMask::ByteSizeLong() const {
return total_size;
}
void FieldMask::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FieldMask)
GOOGLE_DCHECK_NE(&from, this);
const FieldMask* source =
::PROTOBUF_NAMESPACE_ID::DynamicCastToGenerated<FieldMask>(
&from);
if (source == nullptr) {
// @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.FieldMask)
::PROTOBUF_NAMESPACE_ID::internal::ReflectionOps::Merge(from, this);
} else {
// @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.FieldMask)
MergeFrom(*source);
}
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FieldMask::_class_data_ = {
::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
FieldMask::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FieldMask::GetClassData() const { return &_class_data_; }
void FieldMask::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to,
const ::PROTOBUF_NAMESPACE_ID::Message&from) {
static_cast<FieldMask *>(to)->MergeFrom(
static_cast<const FieldMask &>(from));
}
void FieldMask::MergeFrom(const FieldMask& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldMask)
GOOGLE_DCHECK_NE(&from, this);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
(void) cached_has_bits;
paths_.MergeFrom(from.paths_);
}
void FieldMask::CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.FieldMask)
if (&from == this) return;
Clear();
MergeFrom(from);
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}
void FieldMask::CopyFrom(const FieldMask& from) {

@ -137,10 +137,13 @@ class PROTOBUF_EXPORT FieldMask final :
FieldMask* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
return CreateMaybeMessage<FieldMask>(arena);
}
void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
void CopyFrom(const FieldMask& from);
using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
void MergeFrom(const FieldMask& from);
private:
static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from);
public:
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
bool IsInitialized() const final;
@ -160,12 +163,16 @@ class PROTOBUF_EXPORT FieldMask final :
return "google.protobuf.FieldMask";
}
protected:
explicit FieldMask(::PROTOBUF_NAMESPACE_ID::Arena* arena);
explicit FieldMask(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned = false);
private:
static void ArenaDtor(void* object);
inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
public:
static const ClassData _class_data_;
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
// nested types ----------------------------------------------------
@ -232,8 +239,9 @@ inline void FieldMask::clear_paths() {
paths_.Clear();
}
inline std::string* FieldMask::add_paths() {
std::string* _s = _internal_add_paths();
// @@protoc_insertion_point(field_add_mutable:google.protobuf.FieldMask.paths)
return _internal_add_paths();
return _s;
}
inline const std::string& FieldMask::_internal_paths(int index) const {
return paths_.Get(index);
@ -247,12 +255,12 @@ inline std::string* FieldMask::mutable_paths(int index) {
return paths_.Mutable(index);
}
inline void FieldMask::set_paths(int index, const std::string& value) {
// @@protoc_insertion_point(field_set:google.protobuf.FieldMask.paths)
paths_.Mutable(index)->assign(value);
// @@protoc_insertion_point(field_set:google.protobuf.FieldMask.paths)
}
inline void FieldMask::set_paths(int index, std::string&& value) {
// @@protoc_insertion_point(field_set:google.protobuf.FieldMask.paths)
paths_.Mutable(index)->assign(std::move(value));
// @@protoc_insertion_point(field_set:google.protobuf.FieldMask.paths)
}
inline void FieldMask::set_paths(int index, const char* value) {
GOOGLE_DCHECK(value != nullptr);

@ -359,6 +359,176 @@ size_t Reflection::SpaceUsedLong(const Message& message) const {
return total_size;
}
namespace internal {
class SwapFieldHelper {
public:
template <bool unsafe_shallow_swap>
static void SwapRepeatedStringField(const Reflection* r, Message* lhs,
Message* rhs,
const FieldDescriptor* field);
template <bool unsafe_shallow_swap>
static void SwapStringField(const Reflection* r, Message* lhs, Message* rhs,
const FieldDescriptor* field);
static void SwapArenaStringPtr(const std::string* default_ptr,
ArenaStringPtr* lhs, Arena* lhs_arena,
ArenaStringPtr* rhs, Arena* rhs_arena);
template <bool unsafe_shallow_swap>
static void SwapRepeatedMessageField(const Reflection* r, Message* lhs,
Message* rhs,
const FieldDescriptor* field);
template <bool unsafe_shallow_swap>
static void SwapMessageField(const Reflection* r, Message* lhs, Message* rhs,
const FieldDescriptor* field);
static void SwapMessage(const Reflection* r, Message* lhs, Arena* lhs_arena,
Message* rhs, Arena* rhs_arena,
const FieldDescriptor* field);
};
template <bool unsafe_shallow_swap>
void SwapFieldHelper::SwapRepeatedStringField(const Reflection* r, Message* lhs,
Message* rhs,
const FieldDescriptor* field) {
switch (field->options().ctype()) {
default:
case FieldOptions::STRING: {
auto* lhs_string = r->MutableRaw<RepeatedPtrFieldBase>(lhs, field);
auto* rhs_string = r->MutableRaw<RepeatedPtrFieldBase>(rhs, field);
if (unsafe_shallow_swap) {
lhs_string->InternalSwap(rhs_string);
} else {
lhs_string->Swap<GenericTypeHandler<std::string>>(rhs_string);
}
break;
}
}
}
template <bool unsafe_shallow_swap>
void SwapFieldHelper::SwapStringField(const Reflection* r, Message* lhs,
Message* rhs,
const FieldDescriptor* field) {
switch (field->options().ctype()) {
default:
case FieldOptions::STRING: {
ArenaStringPtr* lhs_string = r->MutableRaw<ArenaStringPtr>(lhs, field);
ArenaStringPtr* rhs_string = r->MutableRaw<ArenaStringPtr>(rhs, field);
if (unsafe_shallow_swap) {
ArenaStringPtr::UnsafeShallowSwap(lhs_string, rhs_string);
} else {
SwapFieldHelper::SwapArenaStringPtr(
r->DefaultRaw<ArenaStringPtr>(field).GetPointer(), //
lhs_string, lhs->GetArenaForAllocation(), //
rhs_string, rhs->GetArenaForAllocation());
}
break;
}
}
}
void SwapFieldHelper::SwapArenaStringPtr(const std::string* default_ptr,
ArenaStringPtr* lhs, Arena* lhs_arena,
ArenaStringPtr* rhs,
Arena* rhs_arena) {
if (lhs_arena == rhs_arena) {
ArenaStringPtr::InternalSwap(default_ptr, lhs, lhs_arena, rhs, rhs_arena);
} else if (lhs->IsDefault(default_ptr) && rhs->IsDefault(default_ptr)) {
// Nothing to do.
} else if (lhs->IsDefault(default_ptr)) {
lhs->Set(default_ptr, rhs->Get(), lhs_arena);
// rhs needs to be destroyed before overwritten.
rhs->Destroy(default_ptr, rhs_arena);
rhs->UnsafeSetDefault(default_ptr);
} else if (rhs->IsDefault(default_ptr)) {
rhs->Set(default_ptr, lhs->Get(), rhs_arena);
// lhs needs to be destroyed before overwritten.
lhs->Destroy(default_ptr, lhs_arena);
lhs->UnsafeSetDefault(default_ptr);
} else {
std::string temp = lhs->Get();
lhs->Set(default_ptr, rhs->Get(), lhs_arena);
rhs->Set(default_ptr, std::move(temp), rhs_arena);
}
}
template <bool unsafe_shallow_swap>
void SwapFieldHelper::SwapRepeatedMessageField(const Reflection* r,
Message* lhs, Message* rhs,
const FieldDescriptor* field) {
if (IsMapFieldInApi(field)) {
auto* lhs_map = r->MutableRaw<MapFieldBase>(lhs, field);
auto* rhs_map = r->MutableRaw<MapFieldBase>(rhs, field);
if (unsafe_shallow_swap) {
lhs_map->UnsafeShallowSwap(rhs_map);
} else {
lhs_map->Swap(rhs_map);
}
} else {
auto* lhs_rm = r->MutableRaw<RepeatedPtrFieldBase>(lhs, field);
auto* rhs_rm = r->MutableRaw<RepeatedPtrFieldBase>(rhs, field);
if (unsafe_shallow_swap) {
lhs_rm->InternalSwap(rhs_rm);
} else {
lhs_rm->Swap<GenericTypeHandler<Message>>(rhs_rm);
}
}
}
template <bool unsafe_shallow_swap>
void SwapFieldHelper::SwapMessageField(const Reflection* r, Message* lhs,
Message* rhs,
const FieldDescriptor* field) {
if (unsafe_shallow_swap) {
std::swap(*r->MutableRaw<Message*>(lhs, field),
*r->MutableRaw<Message*>(rhs, field));
} else {
SwapMessage(r, lhs, lhs->GetArenaForAllocation(), rhs,
rhs->GetArenaForAllocation(), field);
}
}
void SwapFieldHelper::SwapMessage(const Reflection* r, Message* lhs,
Arena* lhs_arena, Message* rhs,
Arena* rhs_arena,
const FieldDescriptor* field) {
Message** lhs_sub = r->MutableRaw<Message*>(lhs, field);
Message** rhs_sub = r->MutableRaw<Message*>(rhs, field);
if (*lhs_sub == *rhs_sub) return;
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
if (lhs_arena != nullptr && lhs_arena == rhs_arena) {
#else // PROTOBUF_FORCE_COPY_IN_SWAP
if (lhs_arena == rhs_arena) {
#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
std::swap(*lhs_sub, *rhs_sub);
return;
}
if (*lhs_sub != nullptr && *rhs_sub != nullptr) {
(*lhs_sub)->GetReflection()->Swap(*lhs_sub, *rhs_sub);
} else if (*lhs_sub == nullptr) {
*lhs_sub = (*rhs_sub)->New(lhs_arena);
(*lhs_sub)->CopyFrom(**rhs_sub);
r->ClearField(rhs, field);
// Ensures has bit is unchanged after ClearField.
r->SetBit(rhs, field);
} else {
*rhs_sub = (*lhs_sub)->New(rhs_arena);
(*rhs_sub)->CopyFrom(**lhs_sub);
r->ClearField(lhs, field);
// Ensures has bit is unchanged after ClearField.
r->SetBit(lhs, field);
}
}
} // namespace internal
void Reflection::SwapField(Message* message1, Message* message2,
const FieldDescriptor* field) const {
if (field->is_repeated()) {
@ -380,24 +550,12 @@ void Reflection::SwapField(Message* message1, Message* message2,
#undef SWAP_ARRAYS
case FieldDescriptor::CPPTYPE_STRING:
switch (field->options().ctype()) {
default: // TODO(kenton): Support other string reps.
case FieldOptions::STRING:
MutableRaw<RepeatedPtrFieldBase>(message1, field)
->Swap<GenericTypeHandler<std::string> >(
MutableRaw<RepeatedPtrFieldBase>(message2, field));
break;
}
internal::SwapFieldHelper::SwapRepeatedStringField<false>(
this, message1, message2, field);
break;
case FieldDescriptor::CPPTYPE_MESSAGE:
if (IsMapFieldInApi(field)) {
MutableRaw<MapFieldBase>(message1, field)
->Swap(MutableRaw<MapFieldBase>(message2, field));
} else {
MutableRaw<RepeatedPtrFieldBase>(message1, field)
->Swap<GenericTypeHandler<Message> >(
MutableRaw<RepeatedPtrFieldBase>(message2, field));
}
internal::SwapFieldHelper::SwapRepeatedMessageField<false>(
this, message1, message2, field);
break;
default:
@ -421,70 +579,13 @@ void Reflection::SwapField(Message* message1, Message* message2,
SWAP_VALUES(ENUM, int);
#undef SWAP_VALUES
case FieldDescriptor::CPPTYPE_MESSAGE:
if (message1->GetArenaForAllocation() ==
message2->GetArenaForAllocation()) {
std::swap(*MutableRaw<Message*>(message1, field),
*MutableRaw<Message*>(message2, field));
} else {
Message** sub_msg1 = MutableRaw<Message*>(message1, field);
Message** sub_msg2 = MutableRaw<Message*>(message2, field);
if (*sub_msg1 == nullptr && *sub_msg2 == nullptr) break;
if (*sub_msg1 && *sub_msg2) {
(*sub_msg1)->GetReflection()->Swap(*sub_msg1, *sub_msg2);
break;
}
if (*sub_msg1 == nullptr) {
*sub_msg1 = (*sub_msg2)->New(message1->GetArenaForAllocation());
(*sub_msg1)->CopyFrom(**sub_msg2);
ClearField(message2, field);
// Ensures has bit is unchanged after ClearField.
SetBit(message2, field);
} else {
*sub_msg2 = (*sub_msg1)->New(message2->GetArenaForAllocation());
(*sub_msg2)->CopyFrom(**sub_msg1);
ClearField(message1, field);
// Ensures has bit is unchanged after ClearField.
SetBit(message1, field);
}
}
internal::SwapFieldHelper::SwapMessageField<false>(this, message1,
message2, field);
break;
case FieldDescriptor::CPPTYPE_STRING:
switch (field->options().ctype()) {
default: // TODO(kenton): Support other string reps.
case FieldOptions::STRING: {
const std::string* default_ptr =
DefaultRaw<ArenaStringPtr>(field).GetPointer();
Arena* arena1 = message1->GetArenaForAllocation();
Arena* arena2 = message2->GetArenaForAllocation();
ArenaStringPtr* string1 =
MutableRaw<ArenaStringPtr>(message1, field);
ArenaStringPtr* string2 =
MutableRaw<ArenaStringPtr>(message2, field);
if (message1->GetOwningArena() == message2->GetOwningArena()) {
ArenaStringPtr::InternalSwap(default_ptr, string1, arena1,
string2, arena2);
} else if (string1->IsDefault(default_ptr) &&
string2->IsDefault(default_ptr)) {
// Nothing to do.
} else if (string1->IsDefault(default_ptr)) {
string1->Set(default_ptr, string2->Get(), arena1);
// string2 needs to be destroyed before overwritten.
string2->Destroy(default_ptr, arena2);
string2->UnsafeSetDefault(default_ptr);
} else if (string2->IsDefault(default_ptr)) {
string2->Set(default_ptr, string1->Get(), arena2);
// string1 needs to be destroyed before overwritten.
string1->Destroy(default_ptr, arena1);
string1->UnsafeSetDefault(default_ptr);
} else {
std::string temp = string1->Get();
string1->Set(default_ptr, string2->Get(), arena1);
string2->Set(default_ptr, std::move(temp), arena2);
}
} break;
}
internal::SwapFieldHelper::SwapStringField<false>(this, message1,
message2, field);
break;
default:
@ -493,6 +594,55 @@ void Reflection::SwapField(Message* message1, Message* message2,
}
}
void Reflection::UnsafeShallowSwapField(Message* message1, Message* message2,
const FieldDescriptor* field) const {
GOOGLE_DCHECK_EQ(message1->GetArenaForAllocation(),
message2->GetArenaForAllocation());
if (!field->is_repeated()) {
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
internal::SwapFieldHelper::SwapMessageField<true>(this, message1,
message2, field);
} else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
internal::SwapFieldHelper::SwapStringField<true>(this, message1, message2,
field);
} else {
SwapField(message1, message2, field);
}
return;
}
switch (field->cpp_type()) {
#define SHALLOW_SWAP_ARRAYS(CPPTYPE, TYPE) \
case FieldDescriptor::CPPTYPE_##CPPTYPE: \
MutableRaw<RepeatedField<TYPE>>(message1, field) \
->InternalSwap(MutableRaw<RepeatedField<TYPE>>(message2, field)); \
break;
SHALLOW_SWAP_ARRAYS(INT32, int32);
SHALLOW_SWAP_ARRAYS(INT64, int64);
SHALLOW_SWAP_ARRAYS(UINT32, uint32);
SHALLOW_SWAP_ARRAYS(UINT64, uint64);
SHALLOW_SWAP_ARRAYS(FLOAT, float);
SHALLOW_SWAP_ARRAYS(DOUBLE, double);
SHALLOW_SWAP_ARRAYS(BOOL, bool);
SHALLOW_SWAP_ARRAYS(ENUM, int);
#undef SHALLOW_SWAP_ARRAYS
case FieldDescriptor::CPPTYPE_STRING:
internal::SwapFieldHelper::SwapRepeatedStringField<true>(this, message1,
message2, field);
break;
case FieldDescriptor::CPPTYPE_MESSAGE:
internal::SwapFieldHelper::SwapRepeatedMessageField<true>(
this, message1, message2, field);
break;
default:
GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
}
}
void Reflection::SwapOneofField(Message* message1, Message* message2,
const OneofDescriptor* oneof_descriptor) const {
GOOGLE_DCHECK(!oneof_descriptor->is_synthetic());
@ -609,6 +759,45 @@ void Reflection::SwapOneofField(Message* message1, Message* message2,
}
}
void Reflection::UnsafeShallowSwapOneofField(
Message* message1, Message* message2,
const OneofDescriptor* oneof_descriptor) const {
GOOGLE_DCHECK_EQ(message1->GetArenaForAllocation(),
message2->GetArenaForAllocation());
uint32 oneof_case1 = GetOneofCase(*message1, oneof_descriptor);
const FieldDescriptor* field1 =
oneof_case1 > 0 ? descriptor_->FindFieldByNumber(oneof_case1) : nullptr;
uint32 oneof_case2 = GetOneofCase(*message2, oneof_descriptor);
const FieldDescriptor* field2 =
oneof_case2 > 0 ? descriptor_->FindFieldByNumber(oneof_case2) : nullptr;
if ((field1 != nullptr &&
field1->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) ||
(field2 != nullptr &&
field2->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)) {
// Fallback to SwapOneofField for non-message fields.
SwapOneofField(message1, message2, oneof_descriptor);
return;
}
Message* temp_message =
oneof_case1 > 0 ? UnsafeArenaReleaseMessage(message1, field1) : nullptr;
if (oneof_case2 > 0) {
UnsafeArenaSetAllocatedMessage(
message1, UnsafeArenaReleaseMessage(message2, field2), field2);
} else {
ClearOneof(message1, oneof_descriptor);
}
if (oneof_case1 > 0) {
UnsafeArenaSetAllocatedMessage(message2, temp_message, field1);
} else {
ClearOneof(message2, oneof_descriptor);
}
}
void Reflection::Swap(Message* message1, Message* message2) const {
if (message1 == message2) return;
@ -632,7 +821,12 @@ void Reflection::Swap(Message* message1, Message* message2) const {
// Check that both messages are in the same arena (or both on the heap). We
// need to copy all data if not, due to ownership semantics.
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
if (message1->GetOwningArena() == nullptr ||
message1->GetOwningArena() != message2->GetOwningArena()) {
#else // PROTOBUF_FORCE_COPY_IN_SWAP
if (message1->GetOwningArena() != message2->GetOwningArena()) {
#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
// One of the two is guaranteed to have an arena. Switch things around
// to guarantee that message1 has an arena.
Arena* arena = message1->GetOwningArena();
@ -644,7 +838,12 @@ void Reflection::Swap(Message* message1, Message* message2) const {
Message* temp = message1->New(arena);
temp->MergeFrom(*message2);
message2->CopyFrom(*message1);
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
message1->CopyFrom(*temp);
if (arena == nullptr) delete temp;
#else // PROTOBUF_FORCE_COPY_IN_SWAP
Swap(message1, temp);
#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
return;
}
@ -691,7 +890,8 @@ void Reflection::Swap(Message* message1, Message* message2) const {
MutableUnknownFields(message1)->Swap(MutableUnknownFields(message2));
}
void Reflection::SwapFields(
template <bool unsafe_shallow_swap>
void Reflection::SwapFieldsImpl(
Message* message1, Message* message2,
const std::vector<const FieldDescriptor*>& fields) const {
if (message1 == message2) return;
@ -716,13 +916,16 @@ void Reflection::SwapFields(
std::set<int> swapped_oneof;
const int fields_size = static_cast<int>(fields.size());
for (int i = 0; i < fields_size; i++) {
const FieldDescriptor* field = fields[i];
for (const auto* field : fields) {
CheckInvalidAccess(schema_, field);
if (field->is_extension()) {
MutableExtensionSet(message1)->SwapExtension(
MutableExtensionSet(message2), field->number());
if (unsafe_shallow_swap) {
MutableExtensionSet(message1)->UnsafeShallowSwapExtension(
MutableExtensionSet(message2), field->number());
} else {
MutableExtensionSet(message1)->SwapExtension(
MutableExtensionSet(message2), field->number());
}
} else {
if (schema_.InRealOneof(field)) {
int oneof_index = field->containing_oneof()->index();
@ -731,10 +934,19 @@ void Reflection::SwapFields(
continue;
}
swapped_oneof.insert(oneof_index);
SwapOneofField(message1, message2, field->containing_oneof());
if (unsafe_shallow_swap) {
UnsafeShallowSwapOneofField(message1, message2,
field->containing_oneof());
} else {
SwapOneofField(message1, message2, field->containing_oneof());
}
} else {
// Swap field.
SwapField(message1, message2, field);
if (unsafe_shallow_swap) {
UnsafeShallowSwapField(message1, message2, field);
} else {
SwapField(message1, message2, field);
}
// Swap has bit for non-repeated fields. We have already checked for
// oneof already. This has to be done after SwapField, because SwapField
// may depend on the information in has bits.
@ -746,6 +958,18 @@ void Reflection::SwapFields(
}
}
void Reflection::SwapFields(
Message* message1, Message* message2,
const std::vector<const FieldDescriptor*>& fields) const {
SwapFieldsImpl<false>(message1, message2, fields);
}
void Reflection::UnsafeShallowSwapFields(
Message* message1, Message* message2,
const std::vector<const FieldDescriptor*>& fields) const {
SwapFieldsImpl<true>(message1, message2, fields);
}
// -------------------------------------------------------------------
bool Reflection::HasField(const Message& message,
@ -1627,6 +1851,10 @@ void Reflection::UnsafeArenaSetAllocatedMessage(
void Reflection::SetAllocatedMessage(Message* message, Message* sub_message,
const FieldDescriptor* field) const {
#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT
GOOGLE_DCHECK(sub_message->GetOwningArena() == nullptr ||
sub_message->GetOwningArena() == message->GetArenaForAllocation());
#endif // PROTOBUF_INTERNAL_USE_MUST_USE_RESULT
CheckInvalidAccess(schema_, field);
// If message and sub-message are in different memory ownership domains

@ -48,6 +48,8 @@
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/map_test_util.h>
#include <google/protobuf/map_unittest.pb.h>
#include <google/protobuf/test_util.h>
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/arena.h>
@ -61,6 +63,15 @@
namespace google {
namespace protobuf {
class GeneratedMessageReflectionTestHelper {
public:
static void UnsafeShallowSwapFields(
Message* lhs, Message* rhs,
const std::vector<const FieldDescriptor*>& fields) {
lhs->GetReflection()->UnsafeShallowSwapFields(lhs, rhs, fields);
}
};
namespace {
// Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes.
@ -314,6 +325,125 @@ TEST(GeneratedMessageReflectionTest, SwapFieldsAllExtension) {
TestUtil::ExpectAllExtensionsSet(message2);
}
TEST(GeneratedMessageReflectionTest, SwapFieldsAllExtensionArenaHeap) {
Arena arena;
std::unique_ptr<unittest::TestAllExtensions> message1(
Arena::CreateMessage<unittest::TestAllExtensions>(nullptr));
auto* message2 = Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
TestUtil::SetAllExtensions(message1.get());
std::vector<const FieldDescriptor*> fields;
const Reflection* reflection = message1->GetReflection();
reflection->ListFields(*message1, &fields);
reflection->SwapFields(message1.get(), message2, fields);
TestUtil::ExpectExtensionsClear(*message1);
TestUtil::ExpectAllExtensionsSet(*message2);
}
TEST(GeneratedMessageReflectionTest, UnsafeShallowSwapFieldsAll) {
Arena arena;
auto* message1 = Arena::CreateMessage<unittest::TestAllTypes>(&arena);
auto* message2 = Arena::CreateMessage<unittest::TestAllTypes>(&arena);
TestUtil::SetAllFields(message2);
auto* kept_nested_message_ptr = message2->mutable_optional_nested_message();
auto* kept_foreign_message_ptr = message2->mutable_optional_foreign_message();
auto* kept_repeated_nested_message_ptr =
message2->mutable_repeated_nested_message(0);
auto* kept_repeated_foreign_message_ptr =
message2->mutable_repeated_foreign_message(0);
std::vector<const FieldDescriptor*> fields;
const Reflection* reflection = message1->GetReflection();
reflection->ListFields(*message2, &fields);
GeneratedMessageReflectionTestHelper::UnsafeShallowSwapFields(
message1, message2, fields);
TestUtil::ExpectAllFieldsSet(*message1);
TestUtil::ExpectClear(*message2);
// Expects the swap to be shallow. Expects pointer stability to the element of
// the repeated fields (not the container).
EXPECT_EQ(kept_nested_message_ptr,
message1->mutable_optional_nested_message());
EXPECT_EQ(kept_foreign_message_ptr,
message1->mutable_optional_foreign_message());
EXPECT_EQ(kept_repeated_nested_message_ptr,
message1->mutable_repeated_nested_message(0));
EXPECT_EQ(kept_repeated_foreign_message_ptr,
message1->mutable_repeated_foreign_message(0));
}
TEST(GeneratedMessageReflectionTest, UnsafeShallowSwapFieldsMap) {
Arena arena;
auto* message1 = Arena::CreateMessage<unittest::TestMap>(&arena);
auto* message2 = Arena::CreateMessage<unittest::TestMap>(&arena);
MapTestUtil::SetMapFields(message2);
auto* kept_map_int32_fm_ptr =
&(*message2->mutable_map_int32_foreign_message())[0];
std::vector<const FieldDescriptor*> fields;
const Reflection* reflection = message1->GetReflection();
reflection->ListFields(*message2, &fields);
GeneratedMessageReflectionTestHelper::UnsafeShallowSwapFields(
message1, message2, fields);
MapTestUtil::ExpectMapFieldsSet(*message1);
MapTestUtil::ExpectClear(*message2);
// Expects the swap to be shallow.
EXPECT_EQ(kept_map_int32_fm_ptr,
&(*message1->mutable_map_int32_foreign_message())[0]);
}
TEST(GeneratedMessageReflectionTest, UnsafeShallowSwapFieldsAllExtension) {
Arena arena;
auto* message1 = Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
auto* message2 = Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
TestUtil::SetAllExtensions(message1);
auto* kept_nested_message_ext_ptr =
message1->MutableExtension(unittest::optional_nested_message_extension);
auto* kept_foreign_message_ext_ptr =
message1->MutableExtension(unittest::optional_foreign_message_extension);
auto* kept_repeated_nested_message_ext_ptr =
message1->MutableRepeatedExtension(
unittest::repeated_nested_message_extension);
auto* kept_repeated_foreign_message_ext_ptr =
message1->MutableRepeatedExtension(
unittest::repeated_foreign_message_extension);
std::vector<const FieldDescriptor*> fields;
const Reflection* reflection = message1->GetReflection();
reflection->ListFields(*message1, &fields);
GeneratedMessageReflectionTestHelper::UnsafeShallowSwapFields(
message1, message2, fields);
TestUtil::ExpectExtensionsClear(*message1);
TestUtil::ExpectAllExtensionsSet(*message2);
// Expects the swap to be shallow.
EXPECT_EQ(
kept_nested_message_ext_ptr,
message2->MutableExtension(unittest::optional_nested_message_extension));
EXPECT_EQ(
kept_foreign_message_ext_ptr,
message2->MutableExtension(unittest::optional_foreign_message_extension));
EXPECT_EQ(kept_repeated_nested_message_ext_ptr,
message2->MutableRepeatedExtension(
unittest::repeated_nested_message_extension));
EXPECT_EQ(kept_repeated_foreign_message_ext_ptr,
message2->MutableRepeatedExtension(
unittest::repeated_foreign_message_extension));
}
TEST(GeneratedMessageReflectionTest, SwapOneof) {
unittest::TestOneof2 message1, message2;
TestUtil::SetOneof1(&message1);
@ -353,6 +483,46 @@ TEST(GeneratedMessageReflectionTest, SwapFieldsOneof) {
TestUtil::ExpectOneofSet1(message2);
}
TEST(GeneratedMessageReflectionTest, UnsafeShallowSwapFieldsOneof) {
Arena arena;
auto* message1 = Arena::CreateMessage<unittest::TestOneof2>(&arena);
auto* message2 = Arena::CreateMessage<unittest::TestOneof2>(&arena);
TestUtil::SetOneof1(message1);
std::vector<const FieldDescriptor*> fields;
const Descriptor* descriptor = message1->GetDescriptor();
for (int i = 0; i < descriptor->field_count(); i++) {
fields.push_back(descriptor->field(i));
}
GeneratedMessageReflectionTestHelper::UnsafeShallowSwapFields(
message1, message2, fields);
TestUtil::ExpectOneofClear(*message1);
TestUtil::ExpectOneofSet1(*message2);
}
TEST(GeneratedMessageReflectionTest,
UnsafeShallowSwapFieldsOneofExpectShallow) {
Arena arena;
auto* message1 = Arena::CreateMessage<unittest::TestOneof2>(&arena);
auto* message2 = Arena::CreateMessage<unittest::TestOneof2>(&arena);
TestUtil::SetOneof1(message1);
message1->mutable_foo_message()->set_qux_int(1000);
auto* kept_foo_ptr = message1->mutable_foo_message();
std::vector<const FieldDescriptor*> fields;
const Descriptor* descriptor = message1->GetDescriptor();
for (int i = 0; i < descriptor->field_count(); i++) {
fields.push_back(descriptor->field(i));
}
GeneratedMessageReflectionTestHelper::UnsafeShallowSwapFields(
message1, message2, fields);
EXPECT_TRUE(message2->has_foo_message());
EXPECT_EQ(message2->foo_message().qux_int(), 1000);
EXPECT_EQ(kept_foo_ptr, message2->mutable_foo_message());
}
TEST(GeneratedMessageReflectionTest, RemoveLast) {
unittest::TestAllTypes message;
TestUtil::ReflectionTester reflection_tester(

@ -0,0 +1,123 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file contains declarations needed in generated headers for messages
// that use tail-call table parsing. Everything in this file is for internal
// use only.
#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_DECL_H__
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_DECL_H__
#include <cstdint>
#include <type_traits>
#include <google/protobuf/parse_context.h>
#include <google/protobuf/message_lite.h>
namespace google {
namespace protobuf {
namespace internal {
// Additional information about this field:
struct TcFieldData {
constexpr TcFieldData() : data(0) {}
constexpr TcFieldData(uint16_t coded_tag, uint8_t hasbit_idx, uint16_t offset)
: data(static_cast<uint64_t>(offset) << 48 |
static_cast<uint64_t>(hasbit_idx) << 16 | coded_tag) {}
uint16_t coded_tag() const { return static_cast<uint16_t>(data); }
uint8_t hasbit_idx() const { return static_cast<uint8_t>(data >> 16); }
uint16_t offset() const { return static_cast<uint16_t>(data >> 48); }
uint64_t data;
};
struct TailCallParseTableBase;
// TailCallParseFunc is the function pointer type used in the tailcall table.
typedef const char* (*TailCallParseFunc)(MessageLite* msg, const char* ptr,
ParseContext* ctx,
const TailCallParseTableBase* table,
uint64_t hasbits, TcFieldData data);
// Base class for message-level table with info for the tail-call parser.
struct TailCallParseTableBase {
// Common attributes for message layout:
uint16_t has_bits_offset;
uint16_t extension_offset;
uint32_t extension_range_low;
uint32_t extension_range_high;
uint32_t has_bits_required_mask;
const MessageLite* default_instance;
// Handler for fields which are not handled by table dispatch.
TailCallParseFunc fallback;
// Table entry for fast-path tailcall dispatch handling.
struct FieldEntry {
// Target function for dispatch:
TailCallParseFunc target;
// Field data used during parse:
TcFieldData bits;
};
// There is always at least one table entry.
const FieldEntry* table() const {
return reinterpret_cast<const FieldEntry*>(this + 1);
}
};
static_assert(sizeof(TailCallParseTableBase::FieldEntry) <= 16,
"Field entry is too big.");
template <size_t kTableSizeLog2>
struct TailCallParseTable {
TailCallParseTableBase header;
// Entries for each field.
//
// Fields are indexed by the lowest bits of their field number. The field
// number is masked to fit inside the table. Note that the parsing logic
// generally calls `TailCallParseTableBase::table()` instead of accessing
// this field directly.
TailCallParseTableBase::FieldEntry entries[(1 << kTableSizeLog2)];
};
static_assert(std::is_standard_layout<TailCallParseTable<1>>::value,
"TailCallParseTable must be standard layout.");
static_assert(offsetof(TailCallParseTable<1>, entries) ==
sizeof(TailCallParseTableBase),
"Table entries must be laid out after TailCallParseTableBase.");
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_DECL_H__

@ -0,0 +1,53 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cstdint>
#include <google/protobuf/parse_context.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/generated_message_tctable_impl.h>
#include <google/protobuf/message.h>
#include <google/protobuf/unknown_field_set.h>
// clang-format off
#include <google/protobuf/port_def.inc>
// clang-format on
namespace google {
namespace protobuf {
namespace internal {
const char* TcParserBase::GenericFallback(PROTOBUF_TC_PARAM_DECL) {
return GenericFallbackImpl<Message, UnknownFieldSet>(PROTOBUF_TC_PARAM_PASS);
}
} // namespace internal
} // namespace protobuf
} // namespace google

@ -0,0 +1,245 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_IMPL_H__
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_IMPL_H__
#include <cstdint>
#include <type_traits>
#include <google/protobuf/parse_context.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/generated_message_tctable_decl.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/metadata_lite.h>
#include <google/protobuf/port.h>
#include <google/protobuf/wire_format_lite.h>
// Must come last:
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
class Message;
class UnknownFieldSet;
namespace internal {
// PROTOBUF_TC_PARAM_DECL are the parameters for tailcall functions.
//
// Note that this is performance sensitive: changing the parameters will change
// the registers used by the ABI calling convention, which subsequently affects
// register selection logic inside the function.
#define PROTOBUF_TC_PARAM_DECL \
::google::protobuf::MessageLite *msg, const char *ptr, \
::google::protobuf::internal::ParseContext *ctx, \
const ::google::protobuf::internal::TailCallParseTableBase *table, \
uint64_t hasbits, ::google::protobuf::internal::TcFieldData data
// PROTOBUF_TC_PARAM_PASS passes values to match PROTOBUF_TC_PARAM_DECL.
#define PROTOBUF_TC_PARAM_PASS msg, ptr, ctx, table, hasbits, data
class TcParserBase {
public:
static const char* GenericFallback(PROTOBUF_TC_PARAM_DECL);
static const char* GenericFallbackLite(PROTOBUF_TC_PARAM_DECL);
template <typename FieldType, typename TagType>
PROTOBUF_NOINLINE static const char* SingularParseMessage(
PROTOBUF_TC_PARAM_DECL) {
if (PROTOBUF_PREDICT_FALSE(static_cast<TagType>(data.coded_tag()) != 0)) {
return table->fallback(PROTOBUF_TC_PARAM_PASS);
}
ptr += sizeof(TagType);
hasbits |= (1 << data.hasbit_idx());
auto& field = RefAt<FieldType*>(msg, data.offset());
if (field == nullptr) {
auto arena = ctx->data().arena;
if (Arena::is_arena_constructable<FieldType>::value) {
field = Arena::CreateMessage<FieldType>(arena);
} else {
field = Arena::Create<FieldType>(arena);
}
}
SyncHasbits(msg, hasbits, table);
return ctx->ParseMessage(field, ptr);
}
template <typename FieldType, typename TagType>
PROTOBUF_NOINLINE static const char* RepeatedParseMessage(
PROTOBUF_TC_PARAM_DECL) {
if (PROTOBUF_PREDICT_FALSE(static_cast<TagType>(data.coded_tag()) != 0)) {
return table->fallback(PROTOBUF_TC_PARAM_PASS);
}
ptr += sizeof(TagType);
auto& field = RefAt<RepeatedPtrField<FieldType>>(msg, data.offset());
SyncHasbits(msg, hasbits, table);
ptr = ctx->ParseMessage(field.Add(), ptr);
return ptr;
}
template <typename LayoutType, typename TagType>
static const char* RepeatedFixed(PROTOBUF_TC_PARAM_DECL);
template <typename LayoutType, typename TagType>
static const char* PackedFixed(PROTOBUF_TC_PARAM_DECL);
protected:
template <typename T>
static T& RefAt(void* x, size_t offset) {
T* target = reinterpret_cast<T*>(static_cast<char*>(x) + offset);
GOOGLE_DCHECK_EQ(0, reinterpret_cast<uintptr_t>(target) % alignof(T));
return *target;
}
static inline PROTOBUF_ALWAYS_INLINE void SyncHasbits(
MessageLite* msg, uint64_t hasbits, const TailCallParseTableBase* table) {
const uint32_t has_bits_offset = table->has_bits_offset;
if (has_bits_offset) {
// Only the first 32 has-bits are updated. Nothing above those is stored,
// but e.g. messages without has-bits update the upper bits.
RefAt<uint32_t>(msg, has_bits_offset) = static_cast<uint32_t>(hasbits);
}
}
static inline PROTOBUF_ALWAYS_INLINE const char* Return(
PROTOBUF_TC_PARAM_DECL) {
SyncHasbits(msg, hasbits, table);
return ptr;
}
static inline PROTOBUF_ALWAYS_INLINE const char* Error(
PROTOBUF_TC_PARAM_DECL) {
SyncHasbits(msg, hasbits, table);
return nullptr;
}
class ScopedArenaSwap final {
public:
ScopedArenaSwap(MessageLite* msg, ParseContext* ctx)
: ctx_(ctx), saved_(ctx->data().arena) {
ctx_->data().arena = msg->GetArenaForAllocation();
}
ScopedArenaSwap(const ScopedArenaSwap&) = delete;
~ScopedArenaSwap() { ctx_->data().arena = saved_; }
private:
ParseContext* const ctx_;
Arena* const saved_;
};
template <class MessageBaseT, class UnknownFieldsT>
static const char* GenericFallbackImpl(PROTOBUF_TC_PARAM_DECL) {
#define CHK_(x) \
if (PROTOBUF_PREDICT_FALSE(!(x))) return nullptr /* NOLINT */
SyncHasbits(msg, hasbits, table);
uint32_t tag;
ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
CHK_(ptr);
if ((tag & 7) == WireFormatLite::WIRETYPE_END_GROUP || tag == 0) {
ctx->SetLastTag(tag);
return ptr;
}
uint32_t num = tag >> 3;
if (table->extension_range_low <= num &&
num <= table->extension_range_high) {
return RefAt<ExtensionSet>(msg, table->extension_offset)
.ParseField(tag, ptr,
static_cast<const MessageBaseT*>(table->default_instance),
&msg->_internal_metadata_, ctx);
}
return UnknownFieldParse(
tag, msg->_internal_metadata_.mutable_unknown_fields<UnknownFieldsT>(),
ptr, ctx);
#undef CHK_
}
};
// TcParser implements most of the parsing logic for tailcall tables.
//
// This is templated on lg2(table size), since dispatching depends upon the size
// of the table. The template parameter avoids runtime overhead for computing
// the table entry index.
template <uint32_t kPowerOf2>
struct TcParser final : TcParserBase {
// Dispatch to the designated parse function
inline PROTOBUF_ALWAYS_INLINE static const char* TagDispatch(
PROTOBUF_TC_PARAM_DECL) {
const auto coded_tag = UnalignedLoad<uint16_t>(ptr);
constexpr size_t kIdxMask = ((1 << (kPowerOf2)) - 1);
const size_t idx = (coded_tag >> 3) & kIdxMask;
data = table->table()[idx].bits;
data.data ^= coded_tag;
PROTOBUF_MUSTTAIL return table->table()[idx].target(PROTOBUF_TC_PARAM_PASS);
}
// We can only safely call from field to next field if the call is optimized
// to a proper tail call. Otherwise we blow through stack. Clang and gcc
// reliably do this optimization in opt mode, but do not perform this in debug
// mode. Luckily the structure of the algorithm is such that it's always
// possible to just return and use the enclosing parse loop as a trampoline.
static const char* TailCall(PROTOBUF_TC_PARAM_DECL) {
constexpr bool always_return = !PROTOBUF_TAILCALL;
if (always_return || !ctx->DataAvailable(ptr)) {
PROTOBUF_MUSTTAIL return Return(PROTOBUF_TC_PARAM_PASS);
}
PROTOBUF_MUSTTAIL return TagDispatch(PROTOBUF_TC_PARAM_PASS);
}
static const char* ParseLoop(MessageLite* msg, const char* ptr,
ParseContext* ctx,
const TailCallParseTableBase* table) {
ScopedArenaSwap saved(msg, ctx);
const uint32_t has_bits_offset = table->has_bits_offset;
while (!ctx->Done(&ptr)) {
uint64_t hasbits = 0;
if (has_bits_offset) hasbits = RefAt<uint32_t>(msg, has_bits_offset);
ptr = TagDispatch(msg, ptr, ctx, table, hasbits, {});
if (ptr == nullptr) break;
if (ctx->LastTag() != 1) break; // Ended on terminating tag
}
return ptr;
}
template <typename LayoutType, typename TagType>
static const char* SingularFixed(PROTOBUF_TC_PARAM_DECL);
};
// Declare helper functions:
#include <google/protobuf/generated_message_tctable_impl.inc>
} // namespace internal
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_IMPL_H__

@ -0,0 +1,91 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// clang-format off
#ifdef PROTOBUF_TCT_SOURCE
template const char* TcParser<1>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParser<2>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParser<3>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParser<4>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParser<5>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParserBase::RepeatedFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParserBase::PackedFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParser<1>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParser<2>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParser<3>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParser<4>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParser<5>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParserBase::RepeatedFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParserBase::PackedFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParser<1>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParser<2>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParser<3>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParser<4>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParser<5>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParserBase::RepeatedFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParserBase::PackedFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParser<1>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParser<2>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParser<3>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParser<4>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParser<5>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParserBase::RepeatedFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
template const char* TcParserBase::PackedFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
#else
extern template const char* TcParser<1>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParser<2>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParser<3>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParser<4>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParser<5>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParserBase::RepeatedFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParserBase::PackedFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParser<1>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParser<2>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParser<3>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParser<4>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParser<5>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParserBase::RepeatedFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParserBase::PackedFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParser<1>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParser<2>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParser<3>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParser<4>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParser<5>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParserBase::RepeatedFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParserBase::PackedFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParser<1>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParser<2>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParser<3>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParser<4>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParser<5>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParserBase::RepeatedFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
extern template const char* TcParserBase::PackedFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
#endif
// clang-format on

@ -0,0 +1,148 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cstdint>
#include <google/protobuf/parse_context.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/generated_message_tctable_decl.h>
#include <google/protobuf/generated_message_tctable_impl.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/wire_format_lite.h>
// clang-format off
#include <google/protobuf/port_def.inc>
// clang-format on
namespace google {
namespace protobuf {
namespace internal {
const char* TcParserBase::GenericFallbackLite(PROTOBUF_TC_PARAM_DECL) {
return GenericFallbackImpl<MessageLite, std::string>(PROTOBUF_TC_PARAM_PASS);
}
namespace {
// Offset returns the address `offset` bytes after `base`.
inline void* Offset(void* base, uint32_t offset) {
return static_cast<uint8*>(base) + offset;
}
// InvertPacked changes tag bits from the given wire type to length
// delimited. This is the difference expected between packed and non-packed
// repeated fields.
template <WireFormatLite::WireType Wt>
inline PROTOBUF_ALWAYS_INLINE void InvertPacked(TcFieldData& data) {
data.data ^= Wt ^ WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
}
} // namespace
//////////////////////////////////////////////////////////////////////////////
// Fixed fields
//////////////////////////////////////////////////////////////////////////////
template <uint32_t kPowerOf2>
template <typename LayoutType, typename TagType>
const char* TcParser<kPowerOf2>::SingularFixed(PROTOBUF_TC_PARAM_DECL) {
if (PROTOBUF_PREDICT_FALSE(static_cast<TagType>(data.coded_tag()) != 0)) {
return table->fallback(PROTOBUF_TC_PARAM_PASS);
}
ptr += sizeof(TagType); // Consume tag
hasbits |= (1 << data.hasbit_idx());
std::memcpy(Offset(msg, data.offset()), ptr, sizeof(LayoutType));
ptr += sizeof(LayoutType);
// TailCall syncs any pending hasbits:
PROTOBUF_MUSTTAIL return TailCall(PROTOBUF_TC_PARAM_PASS);
}
template <typename LayoutType, typename TagType>
const char* TcParserBase::RepeatedFixed(PROTOBUF_TC_PARAM_DECL) {
if (PROTOBUF_PREDICT_FALSE(static_cast<TagType>(data.coded_tag()) != 0)) {
// Check if the field can be parsed as packed repeated:
constexpr WireFormatLite::WireType fallback_wt =
sizeof(LayoutType) == 4 ? WireFormatLite::WIRETYPE_FIXED32
: WireFormatLite::WIRETYPE_FIXED64;
InvertPacked<fallback_wt>(data);
if (static_cast<TagType>(data.coded_tag()) == 0) {
return PackedFixed<LayoutType, TagType>(PROTOBUF_TC_PARAM_PASS);
} else {
return table->fallback(PROTOBUF_TC_PARAM_PASS);
}
}
auto& field = RefAt<RepeatedField<LayoutType>>(msg, data.offset());
int idx = field.size();
auto elem = field.Add();
int space = field.Capacity() - idx;
idx = 0;
auto expected_tag = UnalignedLoad<TagType>(ptr);
do {
ptr += sizeof(TagType);
std::memcpy(elem + (idx++), ptr, sizeof(LayoutType));
ptr += sizeof(LayoutType);
if (idx >= space) break;
if (!ctx->DataAvailable(ptr)) break;
} while (UnalignedLoad<TagType>(ptr) == expected_tag);
field.AddNAlreadyReserved(idx - 1);
return Return(PROTOBUF_TC_PARAM_PASS);
}
template <typename LayoutType, typename TagType>
const char* TcParserBase::PackedFixed(PROTOBUF_TC_PARAM_DECL) {
if (PROTOBUF_PREDICT_FALSE(static_cast<TagType>(data.coded_tag()) != 0)) {
// Try parsing as non-packed repeated:
constexpr WireFormatLite::WireType fallback_wt =
sizeof(LayoutType) == 4 ? WireFormatLite::WIRETYPE_FIXED32
: WireFormatLite::WIRETYPE_FIXED64;
InvertPacked<fallback_wt>(data);
if (static_cast<TagType>(data.coded_tag()) == 0) {
return RepeatedFixed<LayoutType, TagType>(PROTOBUF_TC_PARAM_PASS);
} else {
return table->fallback(PROTOBUF_TC_PARAM_PASS);
}
}
ptr += sizeof(TagType);
// Since ctx->ReadPackedFixed does not use TailCall<> or Return<>, sync any
// pending hasbits now:
SyncHasbits(msg, hasbits, table);
auto& field = RefAt<RepeatedField<LayoutType>>(msg, data.offset());
int size = ReadSize(&ptr);
// TODO(dlj): add a tailcalling variant of ReadPackedFixed.
return ctx->ReadPackedFixed(ptr, size,
static_cast<RepeatedField<LayoutType>*>(&field));
}
#define PROTOBUF_TCT_SOURCE
#include <google/protobuf/generated_message_tctable_impl.inc>
} // namespace internal
} // namespace protobuf
} // namespace google

@ -721,6 +721,9 @@ MessageLite* GetOwnedMessageInternal(Arena* message_arena,
GOOGLE_DCHECK(Arena::InternalHelper<MessageLite>::GetOwningArena(submessage) ==
submessage_arena);
GOOGLE_DCHECK(message_arena != submessage_arena);
#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT
GOOGLE_DCHECK_EQ(submessage_arena, nullptr);
#endif // PROTOBUF_INTERNAL_USE_MUST_USE_RESULT
if (message_arena != NULL && submessage_arena == NULL) {
message_arena->Own(submessage);
return submessage;

@ -61,6 +61,11 @@ void MapFieldBase::Swap(MapFieldBase* other) {
InternalSwap(other);
}
void MapFieldBase::UnsafeShallowSwap(MapFieldBase* other) {
GOOGLE_DCHECK_EQ(arena_, other->arena_);
InternalSwap(other);
}
void MapFieldBase::InternalSwap(MapFieldBase* other) {
std::swap(arena_, other->arena_);
std::swap(repeated_field_, other->repeated_field_);

@ -366,6 +366,7 @@ class PROTOBUF_EXPORT MapFieldBase {
virtual void MapEnd(MapIterator* map_iter) const = 0;
virtual void MergeFrom(const MapFieldBase& other) = 0;
virtual void Swap(MapFieldBase* other);
virtual void UnsafeShallowSwap(MapFieldBase* other);
// Sync Map with repeated field and returns the size of map.
virtual int size() const = 0;
virtual void Clear() = 0;
@ -442,6 +443,7 @@ class PROTOBUF_EXPORT MapFieldBase {
friend class ContendedMapCleanTest;
friend class GeneratedMessageReflection;
friend class MapFieldAccessor;
friend class ::PROTOBUF_NAMESPACE_ID::Reflection;
friend class ::PROTOBUF_NAMESPACE_ID::DynamicMessage;
// Virtual helper methods for MapIterator. MapIterator doesn't have the
@ -567,6 +569,7 @@ class MapField : public TypeDefinedMapFieldBase<Key, T> {
void Clear() override;
void MergeFrom(const MapFieldBase& other) override;
void Swap(MapFieldBase* other) override;
void UnsafeShallowSwap(MapFieldBase* other) override;
void InternalSwap(MapField* other);
// Used in the implementation of parsing. Caller should take the ownership iff
@ -649,6 +652,7 @@ class PROTOBUF_EXPORT DynamicMapField
bool DeleteMapValue(const MapKey& map_key) override;
void MergeFrom(const MapFieldBase& other) override;
void Swap(MapFieldBase* other) override;
void UnsafeShallowSwap(MapFieldBase* other) override { Swap(other); }
const Map<MapKey, MapValueRef>& GetMap() const override;
Map<MapKey, MapValueRef>* MutableMap() override;

@ -282,6 +282,14 @@ void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::Swap(
impl_.Swap(&other_field->impl_);
}
template <typename Derived, typename Key, typename T,
WireFormatLite::FieldType kKeyFieldType,
WireFormatLite::FieldType kValueFieldType>
void MapField<Derived, Key, T, kKeyFieldType,
kValueFieldType>::UnsafeShallowSwap(MapFieldBase* other) {
InternalSwap(down_cast<MapField*>(other));
}
template <typename Derived, typename Key, typename T,
WireFormatLite::FieldType kKeyFieldType,
WireFormatLite::FieldType kValueFieldType>

@ -79,15 +79,15 @@ using internal::WireFormat;
using internal::WireFormatLite;
void Message::MergeFrom(const Message& from) {
const Descriptor* descriptor = GetDescriptor();
GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
<< ": Tried to merge from a message with a different type. "
"to: "
<< descriptor->full_name()
<< ", "
"from: "
<< from.GetDescriptor()->full_name();
ReflectionOps::Merge(from, this);
auto* class_to = GetClassData();
auto* class_from = from.GetClassData();
auto* merge_to_from = class_to ? class_to->merge_to_from : nullptr;
if (class_to == nullptr || class_to != class_from) {
merge_to_from = [](Message* to, const Message& from) {
ReflectionOps::Merge(from, to);
};
}
merge_to_from(this, from);
}
void Message::CheckTypeAndMergeFrom(const MessageLite& other) {
@ -95,15 +95,40 @@ void Message::CheckTypeAndMergeFrom(const MessageLite& other) {
}
void Message::CopyFrom(const Message& from) {
const Descriptor* descriptor = GetDescriptor();
GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
<< ": Tried to copy from a message with a different type. "
"to: "
<< descriptor->full_name()
<< ", "
"from: "
<< from.GetDescriptor()->full_name();
ReflectionOps::Copy(from, this);
if (&from == this) return;
auto* class_to = GetClassData();
auto* class_from = from.GetClassData();
auto* copy_to_from = class_to ? class_to->copy_to_from : nullptr;
if (class_to == nullptr || class_to != class_from) {
const Descriptor* descriptor = GetDescriptor();
GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
<< ": Tried to copy from a message with a different type. "
"to: "
<< descriptor->full_name()
<< ", "
"from: "
<< from.GetDescriptor()->full_name();
copy_to_from = [](Message* to, const Message& from) {
ReflectionOps::Copy(from, to);
};
}
copy_to_from(this, from);
}
void Message::CopyWithSizeCheck(Message* to, const Message& from) {
#ifndef NDEBUG
size_t from_size = from.ByteSizeLong();
#endif
to->Clear();
#ifndef NDEBUG
GOOGLE_CHECK_EQ(from_size, from.ByteSizeLong())
<< "Source of CopyFrom changed when clearing target. Either "
"source is a nested message in target (not allowed), or "
"another thread is modifying the source.";
#endif
to->GetClassData()->merge_to_from(to, from);
}
std::string Message::GetTypeName() const {

@ -144,6 +144,7 @@ class MessageFactory;
// Defined in other files.
class AssignDescriptorsHelper;
class DynamicMessageFactory;
class GeneratedMessageReflectionTestHelper;
class MapKey;
class MapValueConstRef;
class MapValueRef;
@ -153,6 +154,7 @@ class MapReflectionTester;
namespace internal {
struct DescriptorTable;
class MapFieldBase;
class SwapFieldHelper;
}
class UnknownFieldSet; // unknown_field_set.h
namespace io {
@ -163,6 +165,7 @@ class CodedOutputStream; // coded_stream.h
} // namespace io
namespace python {
class MapReflectionFriend; // scalar_map_container.h
class MessageReflectionFriend;
}
namespace expr {
class CelMapReflectionFriend; // field_backed_map_impl.cc
@ -363,7 +366,28 @@ class PROTOBUF_EXPORT Message : public MessageLite {
// to implement GetDescriptor() and GetReflection() above.
virtual Metadata GetMetadata() const = 0;
inline explicit Message(Arena* arena) : MessageLite(arena) {}
struct ClassData {
// Note: The order of arguments (to, then from) is chosen so that the ABI
// of this function is the same as the CopyFrom method. That is, the
// hidden "this" parameter comes first.
void (*copy_to_from)(Message* to, const Message& from_msg);
void (*merge_to_from)(Message* to, const Message& from_msg);
};
// GetClassData() returns a pointer to a ClassData struct which
// exists in global memory and is unique to each subclass. This uniqueness
// property is used in order to quickly determine whether two messages are
// of the same type.
// TODO(jorg): change to pure virtual
virtual const ClassData* GetClassData() const { return nullptr; }
// CopyWithSizeCheck calls Clear() and then MergeFrom(), and in debug
// builds, checks that calling Clear() on the destination message doesn't
// alter the size of the source. It assumes the messages are known to be
// of the same type, and thus uses GetClassData().
static void CopyWithSizeCheck(Message* to, const Message& from);
inline explicit Message(Arena* arena, bool is_message_owned = false)
: MessageLite(arena, is_message_owned) {}
protected:
@ -476,7 +500,7 @@ class PROTOBUF_EXPORT Reflection final {
void RemoveLast(Message* message, const FieldDescriptor* field) const;
// Removes the last element of a repeated message field, and returns the
// pointer to the caller. Caller takes ownership of the returned pointer.
PROTOBUF_FUTURE_MUST_USE_RESULT Message* ReleaseLast(
PROTOBUF_MUST_USE_RESULT Message* ReleaseLast(
Message* message, const FieldDescriptor* field) const;
// Swap the complete contents of two messages.
@ -613,7 +637,7 @@ class PROTOBUF_EXPORT Reflection final {
// If the field existed (HasField() is true), then the returned pointer will
// be the same as the pointer returned by MutableMessage().
// This function has the same effect as ClearField().
PROTOBUF_FUTURE_MUST_USE_RESULT Message* ReleaseMessage(
PROTOBUF_MUST_USE_RESULT Message* ReleaseMessage(
Message* message, const FieldDescriptor* field,
MessageFactory* factory = nullptr) const;
@ -986,7 +1010,9 @@ class PROTOBUF_EXPORT Reflection final {
friend class ::PROTOBUF_NAMESPACE_ID::MessageLayoutInspector;
friend class ::PROTOBUF_NAMESPACE_ID::AssignDescriptorsHelper;
friend class DynamicMessageFactory;
friend class GeneratedMessageReflectionTestHelper;
friend class python::MapReflectionFriend;
friend class python::MessageReflectionFriend;
friend class util::MessageDifferencer;
#define GOOGLE_PROTOBUF_HAS_CEL_MAP_REFLECTION_FRIEND
friend class expr::CelMapReflectionFriend;
@ -994,6 +1020,7 @@ class PROTOBUF_EXPORT Reflection final {
friend class internal::MapKeySorter;
friend class internal::WireFormat;
friend class internal::ReflectionOps;
friend class internal::SwapFieldHelper;
// Needed for implementing text format for map.
friend class internal::MapFieldPrinterHelper;
@ -1098,14 +1125,33 @@ class PROTOBUF_EXPORT Reflection final {
inline void SwapBit(Message* message1, Message* message2,
const FieldDescriptor* field) const;
// Shallow-swap fields listed in fields vector of two messages. It is the
// caller's responsibility to make sure shallow swap is safe.
void UnsafeShallowSwapFields(
Message* message1, Message* message2,
const std::vector<const FieldDescriptor*>& fields) const;
// This function only swaps the field. Should swap corresponding has_bit
// before or after using this function.
void SwapField(Message* message1, Message* message2,
const FieldDescriptor* field) const;
// Unsafe but shallow version of SwapField.
void UnsafeShallowSwapField(Message* message1, Message* message2,
const FieldDescriptor* field) const;
template <bool unsafe_shallow_swap>
void SwapFieldsImpl(Message* message1, Message* message2,
const std::vector<const FieldDescriptor*>& fields) const;
void SwapOneofField(Message* message1, Message* message2,
const OneofDescriptor* oneof_descriptor) const;
// Unsafe but shallow version of SwapOneofField.
void UnsafeShallowSwapOneofField(
Message* message1, Message* message2,
const OneofDescriptor* oneof_descriptor) const;
inline bool HasOneofField(const Message& message,
const FieldDescriptor* field) const;
inline void SetOneofCase(Message* message,

@ -78,6 +78,8 @@ class ZeroCopyOutputStream;
} // namespace io
namespace internal {
class SwapFieldHelper;
// Tag type used to invoke the constinit constructor overload of some classes.
// Such constructors are internal implementation details of the library.
struct ConstantInitialized {
@ -90,6 +92,7 @@ class ParseContext;
class ExtensionSet;
class LazyField;
class RepeatedPtrFieldBase;
class TcParserBase;
class WireFormatLite;
class WeakFieldMap;
@ -472,14 +475,15 @@ class PROTOBUF_EXPORT MessageLite {
return Arena::CreateMaybeMessage<T>(arena);
}
inline explicit MessageLite(Arena* arena) : _internal_metadata_(arena) {}
inline explicit MessageLite(Arena* arena, bool is_message_owned = false)
: _internal_metadata_(arena, is_message_owned) {}
// Returns the arena, if any, that directly owns this message and its internal
// memory (Arena::Own is different in that the arena doesn't directly own the
// internal memory). This method is used in proto's implementation for
// swapping, moving and setting allocated, for deciding whether the ownership
// of this message or its internal memory could be changed.
Arena* GetOwningArena() const { return _internal_metadata_.arena(); }
Arena* GetOwningArena() const { return _internal_metadata_.owning_arena(); }
// Returns the arena, used for allocating internal objects(e.g., child
// messages, etc), or owning incoming objects (e.g., set allocated).
@ -524,6 +528,8 @@ class PROTOBUF_EXPORT MessageLite {
friend class Reflection;
friend class internal::ExtensionSet;
friend class internal::LazyField;
friend class internal::SwapFieldHelper;
friend class internal::TcParserBase;
friend class internal::WeakFieldMap;
friend class internal::WireFormatLite;

@ -61,8 +61,19 @@ namespace internal {
// allocation and bit 1 == 1 to indicate heap allocation.
class InternalMetadata {
public:
constexpr InternalMetadata() : ptr_(nullptr) {}
explicit InternalMetadata(Arena* arena) : ptr_(arena) {}
constexpr InternalMetadata() : ptr_(0) {}
explicit InternalMetadata(Arena* arena, bool is_message_owned = false)
: ptr_(is_message_owned
? reinterpret_cast<intptr_t>(arena) | kMessageOwnedArenaTagMask
: reinterpret_cast<intptr_t>(arena)) {
GOOGLE_DCHECK(!is_message_owned || arena != nullptr);
}
~InternalMetadata() {
if (HasMessageOwnedArenaTag()) {
delete arena();
}
}
template <typename T>
void Delete() {
@ -72,6 +83,10 @@ class InternalMetadata {
}
}
PROTOBUF_NDEBUG_INLINE Arena* owning_arena() const {
return HasMessageOwnedArenaTag() ? nullptr : arena();
}
PROTOBUF_NDEBUG_INLINE Arena* arena() const {
if (PROTOBUF_PREDICT_FALSE(have_unknown_fields())) {
return PtrValue<ContainerBase>()->arena;
@ -81,10 +96,12 @@ class InternalMetadata {
}
PROTOBUF_NDEBUG_INLINE bool have_unknown_fields() const {
return PtrTag() == kTagContainer;
return HasUnknownFieldsTag();
}
PROTOBUF_NDEBUG_INLINE void* raw_arena_ptr() const { return ptr_; }
PROTOBUF_NDEBUG_INLINE void* raw_arena_ptr() const {
return reinterpret_cast<void*>(ptr_);
}
template <typename T>
PROTOBUF_NDEBUG_INLINE const T& unknown_fields(
@ -137,27 +154,26 @@ class InternalMetadata {
}
private:
void* ptr_;
intptr_t ptr_;
// Tagged pointer implementation.
enum {
// ptr_ is an Arena*.
kTagArena = 0,
// ptr_ is a Container*.
kTagContainer = 1,
};
static constexpr intptr_t kPtrTagMask = 1;
static constexpr intptr_t kUnknownFieldsTagMask = 1;
static constexpr intptr_t kMessageOwnedArenaTagMask = 2;
static constexpr intptr_t kPtrTagMask =
kUnknownFieldsTagMask | kMessageOwnedArenaTagMask;
static constexpr intptr_t kPtrValueMask = ~kPtrTagMask;
// Accessors for pointer tag and pointer value.
PROTOBUF_NDEBUG_INLINE int PtrTag() const {
return reinterpret_cast<intptr_t>(ptr_) & kPtrTagMask;
PROTOBUF_ALWAYS_INLINE bool HasUnknownFieldsTag() const {
return ptr_ & kUnknownFieldsTagMask;
}
PROTOBUF_ALWAYS_INLINE bool HasMessageOwnedArenaTag() const {
return ptr_ & kMessageOwnedArenaTagMask;
}
template <typename U>
U* PtrValue() const {
return reinterpret_cast<U*>(reinterpret_cast<intptr_t>(ptr_) &
kPtrValueMask);
return reinterpret_cast<U*>(ptr_ & kPtrValueMask);
}
// If ptr_'s tag is kTagContainer, it points to an instance of this struct.
@ -181,11 +197,11 @@ class InternalMetadata {
PROTOBUF_NOINLINE T* mutable_unknown_fields_slow() {
Arena* my_arena = arena();
Container<T>* container = Arena::Create<Container<T>>(my_arena);
intptr_t message_owned_arena_tag = ptr_ & kMessageOwnedArenaTagMask;
// Two-step assignment works around a bug in clang's static analyzer:
// https://bugs.llvm.org/show_bug.cgi?id=34198.
ptr_ = container;
ptr_ = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(ptr_) |
kTagContainer);
ptr_ = reinterpret_cast<intptr_t>(container);
ptr_ |= kUnknownFieldsTagMask | message_owned_arena_tag;
container->arena = my_arena;
return &(container->unknown_fields);
}

@ -234,18 +234,6 @@ const char* EpsCopyInputStream::AppendStringFallback(const char* ptr, int size,
}
template <typename Tag, typename T>
const char* EpsCopyInputStream::ReadRepeatedFixed(const char* ptr,
Tag expected_tag,
RepeatedField<T>* out) {
do {
out->Add(UnalignedLoad<T>(ptr));
ptr += sizeof(T);
if (PROTOBUF_PREDICT_FALSE(ptr >= limit_end_)) return ptr;
} while (UnalignedLoad<Tag>(ptr) == expected_tag&& ptr += sizeof(Tag));
return ptr;
}
template <int>
void byteswap(void* p);
template <>
@ -259,44 +247,6 @@ void byteswap<8>(void* p) {
*static_cast<uint64*>(p) = bswap_64(*static_cast<uint64*>(p));
}
template <typename T>
const char* EpsCopyInputStream::ReadPackedFixed(const char* ptr, int size,
RepeatedField<T>* out) {
int nbytes = buffer_end_ + kSlopBytes - ptr;
while (size > nbytes) {
int num = nbytes / sizeof(T);
int old_entries = out->size();
out->Reserve(old_entries + num);
int block_size = num * sizeof(T);
auto dst = out->AddNAlreadyReserved(num);
#ifdef PROTOBUF_LITTLE_ENDIAN
std::memcpy(dst, ptr, block_size);
#else
for (int i = 0; i < num; i++)
dst[i] = UnalignedLoad<T>(ptr + i * sizeof(T));
#endif
size -= block_size;
if (limit_ <= kSlopBytes) return nullptr;
ptr = Next();
if (ptr == nullptr) return nullptr;
ptr += kSlopBytes - (nbytes - block_size);
nbytes = buffer_end_ + kSlopBytes - ptr;
}
int num = size / sizeof(T);
int old_entries = out->size();
out->Reserve(old_entries + num);
int block_size = num * sizeof(T);
auto dst = out->AddNAlreadyReserved(num);
#ifdef PROTOBUF_LITTLE_ENDIAN
std::memcpy(dst, ptr, block_size);
#else
for (int i = 0; i < num; i++) dst[i] = UnalignedLoad<T>(ptr + i * sizeof(T));
#endif
ptr += block_size;
if (size != block_size) return nullptr;
return ptr;
}
const char* EpsCopyInputStream::InitFrom(io::ZeroCopyInputStream* zcis) {
zcis_ = zcis;
const void* data;

@ -376,6 +376,7 @@ class PROTOBUF_EXPORT ParseContext : public EpsCopyInputStream {
struct Data {
const DescriptorPool* pool = nullptr;
MessageFactory* factory = nullptr;
Arena* arena = nullptr;
};
template <typename... T>
@ -658,6 +659,56 @@ PROTOBUF_MUST_USE_RESULT const char* ParseContext::ParseMessage(
return ptr;
}
template <typename Tag, typename T>
const char* EpsCopyInputStream::ReadRepeatedFixed(const char* ptr,
Tag expected_tag,
RepeatedField<T>* out) {
do {
out->Add(UnalignedLoad<T>(ptr));
ptr += sizeof(T);
if (PROTOBUF_PREDICT_FALSE(ptr >= limit_end_)) return ptr;
} while (UnalignedLoad<Tag>(ptr) == expected_tag && (ptr += sizeof(Tag)));
return ptr;
}
template <typename T>
const char* EpsCopyInputStream::ReadPackedFixed(const char* ptr, int size,
RepeatedField<T>* out) {
int nbytes = buffer_end_ + kSlopBytes - ptr;
while (size > nbytes) {
int num = nbytes / sizeof(T);
int old_entries = out->size();
out->Reserve(old_entries + num);
int block_size = num * sizeof(T);
auto dst = out->AddNAlreadyReserved(num);
#ifdef PROTOBUF_LITTLE_ENDIAN
std::memcpy(dst, ptr, block_size);
#else
for (int i = 0; i < num; i++)
dst[i] = UnalignedLoad<T>(ptr + i * sizeof(T));
#endif
size -= block_size;
if (limit_ <= kSlopBytes) return nullptr;
ptr = Next();
if (ptr == nullptr) return nullptr;
ptr += kSlopBytes - (nbytes - block_size);
nbytes = buffer_end_ + kSlopBytes - ptr;
}
int num = size / sizeof(T);
int old_entries = out->size();
out->Reserve(old_entries + num);
int block_size = num * sizeof(T);
auto dst = out->AddNAlreadyReserved(num);
#ifdef PROTOBUF_LITTLE_ENDIAN
std::memcpy(dst, ptr, block_size);
#else
for (int i = 0; i < num; i++) dst[i] = UnalignedLoad<T>(ptr + i * sizeof(T));
#endif
ptr += block_size;
if (size != block_size) return nullptr;
return ptr;
}
template <typename Add>
const char* ReadPackedVarintArray(const char* ptr, const char* end, Add add) {
while (ptr < end) {

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save