diff options
Diffstat (limited to 'user/protobuf')
-rw-r--r-- | user/protobuf/32bit.patch | 121 | ||||
-rw-r--r-- | user/protobuf/APKBUILD | 69 | ||||
-rw-r--r-- | user/protobuf/cxx14.patch | 115 | ||||
-rw-r--r-- | user/protobuf/python-311.patch | 134 |
4 files changed, 408 insertions, 31 deletions
diff --git a/user/protobuf/32bit.patch b/user/protobuf/32bit.patch new file mode 100644 index 000000000..4630d8afa --- /dev/null +++ b/user/protobuf/32bit.patch @@ -0,0 +1,121 @@ +From 5f4a52d9bff7595ec47fb6727662a1cada3cd404 Mon Sep 17 00:00:00 2001 +From: Mike Kruskal <mkruskal@google.com> +Date: Thu, 15 Sep 2022 10:23:23 -0700 +Subject: [PATCH 3/7] Patching static assert test failure + +--- + src/google/protobuf/extension_set_unittest.cc | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc +index 8b436bc20c9..84da3c5465a 100644 +--- a/src/google/protobuf/extension_set_unittest.cc ++++ b/src/google/protobuf/extension_set_unittest.cc +@@ -855,8 +855,10 @@ TEST(ExtensionSetTest, SpaceUsedExcludingSelf) { + const size_t old_capacity = \ + message->GetRepeatedExtension(unittest::repeated_##type##_extension) \ + .Capacity(); \ +- EXPECT_GE(old_capacity, \ +- (RepeatedFieldLowerClampLimit<cpptype, sizeof(void*)>())); \ ++ EXPECT_GE( \ ++ old_capacity, \ ++ (RepeatedFieldLowerClampLimit<cpptype, std::max(sizeof(cpptype), \ ++ sizeof(void*))>())); \ + for (int i = 0; i < 16; ++i) { \ + message->AddExtension(unittest::repeated_##type##_extension, value); \ + } \ + +From c94b66706bec17d918495f4715183a5eaf0f8044 Mon Sep 17 00:00:00 2001 +From: Mike Kruskal <mkruskal@google.com> +Date: Thu, 15 Sep 2022 11:31:31 -0700 +Subject: [PATCH 4/7] Test fixes for 32-bit architectures + +--- + .../protobuf/io/zero_copy_stream_unittest.cc | 3 ++ + .../protobuf/repeated_field_unittest.cc | 4 +-- + src/google/protobuf/util/time_util_test.cc | 28 +++++++++++-------- + 3 files changed, 22 insertions(+), 13 deletions(-) + +diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc +index d82354e571b..d656da5f13b 100644 +--- a/src/google/protobuf/io/zero_copy_stream_unittest.cc ++++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc +@@ -720,6 +720,9 @@ TEST_F(IoTest, StringIo) { + + // Verifies that outputs up to kint32max can be created. + TEST_F(IoTest, LargeOutput) { ++ // Filter out this test on 32-bit architectures. ++ if(sizeof(void*) < 8) return; ++ + std::string str; + StringOutputStream output(&str); + void* unused_data; +diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc +index eb0b9091cf8..3baf6f25bb2 100644 +--- a/src/google/protobuf/repeated_field_unittest.cc ++++ b/src/google/protobuf/repeated_field_unittest.cc +@@ -429,14 +429,14 @@ TEST(RepeatedField, ReserveNothing) { + + TEST(RepeatedField, ReserveLowerClamp) { + int clamped_value = internal::CalculateReserveSize<bool, sizeof(void*)>(0, 1); +- EXPECT_GE(clamped_value, 8 / sizeof(bool)); ++ EXPECT_GE(clamped_value, sizeof(void*) / sizeof(bool)); + EXPECT_EQ((internal::RepeatedFieldLowerClampLimit<bool, sizeof(void*)>()), + clamped_value); + // EXPECT_EQ(clamped_value, (internal::CalculateReserveSize<bool, + // sizeof(void*)>( clamped_value, 2))); + + clamped_value = internal::CalculateReserveSize<int, sizeof(void*)>(0, 1); +- EXPECT_GE(clamped_value, 8 / sizeof(int)); ++ EXPECT_GE(clamped_value, sizeof(void*) / sizeof(int)); + EXPECT_EQ((internal::RepeatedFieldLowerClampLimit<int, sizeof(void*)>()), + clamped_value); + // EXPECT_EQ(clamped_value, (internal::CalculateReserveSize<int, +diff --git a/src/google/protobuf/util/time_util_test.cc b/src/google/protobuf/util/time_util_test.cc +index 464e57b4ee5..dceb6dbe2bf 100644 +--- a/src/google/protobuf/util/time_util_test.cc ++++ b/src/google/protobuf/util/time_util_test.cc +@@ -48,15 +48,18 @@ using google::protobuf::Timestamp; + namespace { + + TEST(TimeUtilTest, TimestampStringFormat) { +- Timestamp begin, end; +- EXPECT_TRUE(TimeUtil::FromString("0001-01-01T00:00:00Z", &begin)); +- EXPECT_EQ(TimeUtil::kTimestampMinSeconds, begin.seconds()); +- EXPECT_EQ(0, begin.nanos()); +- EXPECT_TRUE(TimeUtil::FromString("9999-12-31T23:59:59.999999999Z", &end)); +- EXPECT_EQ(TimeUtil::kTimestampMaxSeconds, end.seconds()); +- EXPECT_EQ(999999999, end.nanos()); +- EXPECT_EQ("0001-01-01T00:00:00Z", TimeUtil::ToString(begin)); +- EXPECT_EQ("9999-12-31T23:59:59.999999999Z", TimeUtil::ToString(end)); ++ // These these are out of bounds for 32-bit architectures. ++ if(sizeof(time_t) >= sizeof(uint64_t)) { ++ Timestamp begin, end; ++ EXPECT_TRUE(TimeUtil::FromString("0001-01-01T00:00:00Z", &begin)); ++ EXPECT_EQ(TimeUtil::kTimestampMinSeconds, begin.seconds()); ++ EXPECT_EQ(0, begin.nanos()); ++ EXPECT_TRUE(TimeUtil::FromString("9999-12-31T23:59:59.999999999Z", &end)); ++ EXPECT_EQ(TimeUtil::kTimestampMaxSeconds, end.seconds()); ++ EXPECT_EQ(999999999, end.nanos()); ++ EXPECT_EQ("0001-01-01T00:00:00Z", TimeUtil::ToString(begin)); ++ EXPECT_EQ("9999-12-31T23:59:59.999999999Z", TimeUtil::ToString(end)); ++ } + + // Test negative timestamps. + Timestamp time = TimeUtil::NanosecondsToTimestamp(-1); +@@ -94,9 +97,12 @@ TEST(TimeUtilTest, DurationStringFormat) { + EXPECT_TRUE(TimeUtil::FromString("0001-01-01T00:00:00Z", &begin)); + EXPECT_TRUE(TimeUtil::FromString("9999-12-31T23:59:59.999999999Z", &end)); + +- EXPECT_EQ("315537897599.999999999s", TimeUtil::ToString(end - begin)); ++ // These these are out of bounds for 32-bit architectures. ++ if(sizeof(time_t) >= sizeof(uint64_t)) { ++ EXPECT_EQ("315537897599.999999999s", TimeUtil::ToString(end - begin)); ++ EXPECT_EQ("-315537897599.999999999s", TimeUtil::ToString(begin - end)); ++ } + EXPECT_EQ(999999999, (end - begin).nanos()); +- EXPECT_EQ("-315537897599.999999999s", TimeUtil::ToString(begin - end)); + EXPECT_EQ(-999999999, (begin - end).nanos()); + + // Generated output should contain 3, 6, or 9 fractional digits. + diff --git a/user/protobuf/APKBUILD b/user/protobuf/APKBUILD index 78a480016..57708bda2 100644 --- a/user/protobuf/APKBUILD +++ b/user/protobuf/APKBUILD @@ -1,11 +1,11 @@ -# Contributor: Kiyoshi Aman <kiyoshi.aman@gmail.com> +# Contributor: Síle Ekaterin Liszka <sheila@vulpine.house> # Contributor: Natanael Copa <ncopa@alpinelinux.org> # Maintainer: Dan Theisen <djt@hxx.in> pkgname=protobuf _gemname=google-protobuf -pkgver=3.8.0 -_tstver=1.8.1 -pkgrel=0 +pkgver=3.20.3 +_tstver=8d51dc50eb7e7698427fed81b85edad0e032112e +pkgrel=1 pkgdesc="Library for extensible, efficient structure packing" url="https://github.com/google/protobuf" arch="all" @@ -13,39 +13,49 @@ options="!check" # Broken everywhere. license="BSD-3-Clause" depends_dev="zlib-dev" makedepends="$depends_dev autoconf automake libtool ruby ruby-dev ruby-rake - ruby-rake-compiler python3 python3-dev" + ruby-rake-compiler ruby-io-console ruby-irb ruby-power_assert + ruby-rake-compiler ruby-test-unit ruby-reline ruby-rubygems-tasks + python3 python3-dev cmake" checkdepends="ruby-json ruby-test-unit" subpackages="ruby-$_gemname:_ruby py3-$pkgname:_python $pkgname-dev $pkgname-vim::noarch" source="$pkgname-$pkgver.tar.gz::https://github.com/google/$pkgname/archive/v$pkgver.tar.gz - googletest-$_tstver.tar.gz::https://github.com/google/googletest/archive/release-$_tstver.tar.gz" + googletest-$_tstver.tar.gz::https://github.com/google/googletest/archive/$_tstver.tar.gz + cxx14.patch + 32bit.patch + python-311.patch + " prepare() { default_prepare - cd "$builddir" - ./autogen.sh - # symlink tests to the test directory - rm -rf third_party/* - ln -sf "$srcdir"/googletest-release-$_tstver \ + rm -rf third_party/googletest + ln -sf "$srcdir"/googletest-$_tstver \ "$builddir"/third_party/googletest } build() { # Build Protobuf - cd "$builddir" - CXXFLAGS="$CXXFLAGS -fno-delete-null-pointer-checks" LDFLAGS="$LDFLAGS -latomic" \ - ./configure --prefix=/usr \ - --sysconfdir=/etc \ - --mandir=/usr/share/man \ - --infodir=/usr/share/info \ - --localstatedir=/var - make + if [ "$CBUILD" != "$CHOST" ]; then + CMAKE_CROSSOPTS="-DCMAKE_SYSTEM_NAME=Linux -DCMAKE_HOST_SYSTEM_NAME=Linux" + fi + cmake \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DCMAKE_INSTALL_LIBDIR=lib \ + -DBUILD_SHARED_LIBS=True \ + -DCMAKE_BUILD_TYPE=RelWithDebugInfo \ + -DCMAKE_CXX_FLAGS="$CXXFLAGS" \ + -DCMAKE_C_FLAGS="$CFLAGS" \ + ${CMAKE_CROSSOPTS} cmake + make -j1 # Build for Ruby cd "$builddir"/ruby # Generate proto files for built-in protocols. - rake genproto + export LD_LIBRARY_PATH=${builddir} + export CPPFLAGS="-L${builddir}" + export PATH="${builddir}:$PATH" + rake gem build $_gemname.gemspec gem install --local \ --install-dir dist \ @@ -56,20 +66,15 @@ build() { # Build for Python 3 cd "$builddir"/python - export LD_LIBRARY_PATH=${builddir}/src/.libs python3 setup.py build --cpp_implementation # Build test-suite - local test; for test in googletest googlemock; do - cd "$builddir/third_party/googletest/$test" - autoreconf -vfi - ./configure - make - done + cd "$builddir"/third_party/googletest/ + cmake . + make -j1 } check() { - cd "$builddir" make check cd "$builddir"/ruby rake test @@ -78,7 +83,6 @@ check() { } package() { - cd "$builddir" make DESTDIR="$pkgdir" install } @@ -116,5 +120,8 @@ vim() { "$subpkgdir"/usr/share/vim/vimfiles/syntax/proto.vim } -sha512sums="ba27c64e5193cd4a144bf0c9dc0d195fbbe6e580aaca01960362f0f185074588ca40046d3bcea76e1deae7508b722f6c5be484ea957122ae8e98229c7c3a4ad2 protobuf-3.8.0.tar.gz -e6283c667558e1fd6e49fa96e52af0e415a3c8037afe1d28b7ff1ec4c2ef8f49beb70a9327b7fc77eb4052a58c4ccad8b5260ec90e4bceeac7a46ff59c4369d7 googletest-1.8.1.tar.gz" +sha512sums="01d6703bdbe769a1200ee6e4ebcdcb99688ec21f576988c60d82ec36e0822820fb245fcb4ca53293143d53e666d748b5a0c6937bc659fb3cdc4cd9b05ed12a1c protobuf-3.20.3.tar.gz +f7f804abf68af5e4e6cd767151773394fb8297d7d7fc878532ebb22b8c41d13554f68fa38a27470d458b590259a939e93cee7e5f5f6de8f1726c7ce85a606099 googletest-8d51dc50eb7e7698427fed81b85edad0e032112e.tar.gz +faf8962f0c7f1e4053b28a712b31ac9b254b17986326d2188d6edcc609f4b52f4cb85766c4bc02c6b9bc7bc30e2061f940a3089db54eb6056f729a80c1cfa891 cxx14.patch +2dfb540395460f0ea9fad663851633b29fa368a6ec99a88a42e31d7547034191679ef868c0ec67613d070659d4e322dc942b54b21793764e3d2342927977c7eb 32bit.patch +acb8f0bfec92ff969699c909e509f28c1b8c95acb739ce9c3fedaa3f961e2b799190d9eeb4c6022b7cc9244aa7e6c47640cec077dff9382960ea3fc65b24e906 python-311.patch" diff --git a/user/protobuf/cxx14.patch b/user/protobuf/cxx14.patch new file mode 100644 index 000000000..bd7b5c374 --- /dev/null +++ b/user/protobuf/cxx14.patch @@ -0,0 +1,115 @@ +From 500cbd7b90fa7eb5716a3bbc6aa788ada028a1bf Mon Sep 17 00:00:00 2001 +From: Adam Cozzette <acozzette@google.com> +Date: Thu, 11 Aug 2022 18:22:15 -0700 +Subject: [PATCH] Upgrade third_party/googletest submodule to current main + branch (#10393) + +* Upgrade third_party/googletest submodule to current main branch + +We can finally do this upgrade now that we have dropped our autotools +build. Googletest recommends living at head, so let's go straight to the +most recent commit on main. For some reason the googletest archive is +not present in the Bazel build mirror, so I removed that entry and just +left the GitHub download link in our WORKSPACE file. + +Googletest now requires C++14, so I updated all the C++11 flags I could +find to C++14 instead. I added a .bazelrc file to add -std=c++14 for all +our Bazel builds. + +* Delete the empty //src/google/protobuf:protobuf_test target + +* Avoid building C++ unit tests in aarch64 jobs for Python and Ruby +--- + .bazelrc | 1 + + CMakeLists.txt | 8 ++++---- + WORKSPACE | 7 +++---- + examples/Makefile | 4 ++-- + python/setup.py | 2 +- + 5 files changed, 14 insertions(+), 24 deletions(-) + create mode 100644 .bazelrc + +diff --git a/.bazelrc b/.bazelrc +new file mode 100644 +index 00000000000..f93facf00a8 +--- /dev/null ++++ b/.bazelrc +@@ -0,0 +1 @@ ++build --cxxopt=-std=c++14 +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 345d7d05a49..b343c64e48e 100644 +--- a/cmake/CMakeLists.txt ++++ b/cmake/CMakeLists.txt +@@ -32,11 +32,11 @@ if(protobuf_DEPRECATED_CMAKE_SUBDIRECTORY_USAGE) + get_filename_component(protobuf_SOURCE_DIR ${protobuf_SOURCE_DIR} DIRECTORY) + endif() + +-# Add c++11 flags ++# Add c++14 flags + if (CYGWIN) +- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") ++ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14") + else() +- set(CMAKE_CXX_STANDARD 11) ++ set(CMAKE_CXX_STANDARD 14) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) + endif() +@@ -187,7 +187,7 @@ set(protobuf_LINK_LIBATOMIC false) + if (NOT MSVC) + include(CheckCXXSourceCompiles) + set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) +- set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} -std=c++11) ++ set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} -std=c++14) + check_cxx_source_compiles(" + #include <atomic> + int main() { +diff --git a/WORKSPACE b/WORKSPACE +index ebe53315f03..20e7415a629 100644 +--- a/WORKSPACE ++++ b/WORKSPACE +@@ -9,11 +9,10 @@ local_repository( + + http_archive( + name = "com_google_googletest", +- sha256 = "9dc9157a9a1551ec7a7e43daea9a694a0bb5fb8bec81235d8a1e6ef64c716dcb", +- strip_prefix = "googletest-release-1.10.0", ++ sha256 = "ea54c9845568cb31c03f2eddc7a40f7f83912d04ab977ff50ec33278119548dd", ++ strip_prefix = "googletest-4c9a3bb62bf3ba1f1010bf96f9c8ed767b363774", + urls = [ +- "https://mirror.bazel.build/github.com/google/googletest/archive/release-1.10.0.tar.gz", +- "https://github.com/google/googletest/archive/release-1.10.0.tar.gz", ++ "https://github.com/google/googletest/archive/4c9a3bb62bf3ba1f1010bf96f9c8ed767b363774.tar.gz", + ], + ) + +diff --git a/examples/Makefile b/examples/Makefile +index 2a64b64fe37..ef7a4ef58e9 100644 +--- a/examples/Makefile ++++ b/examples/Makefile +@@ -41,11 +41,11 @@ protoc_middleman_dart: addressbook.proto + + add_person_cpp: add_person.cc protoc_middleman + pkg-config --cflags protobuf # fails if protobuf is not installed +- c++ -std=c++11 add_person.cc addressbook.pb.cc -o add_person_cpp `pkg-config --cflags --libs protobuf` ++ c++ -std=c++14 add_person.cc addressbook.pb.cc -o add_person_cpp `pkg-config --cflags --libs protobuf` + + list_people_cpp: list_people.cc protoc_middleman + pkg-config --cflags protobuf # fails if protobuf is not installed +- c++ -std=c++11 list_people.cc addressbook.pb.cc -o list_people_cpp `pkg-config --cflags --libs protobuf` ++ c++ -std=c++14 list_people.cc addressbook.pb.cc -o list_people_cpp `pkg-config --cflags --libs protobuf` + + add_person_dart: add_person.dart protoc_middleman_dart + +diff --git a/python/setup.py b/python/setup.py +index 283c99af607..3364ba9f7ad 100755 +--- a/python/setup.py ++++ b/python/setup.py +@@ -331,7 +331,7 @@ def HasLibraryDirsOpt(): + extra_compile_args.append('-Wno-invalid-offsetof') + extra_compile_args.append('-Wno-sign-compare') + extra_compile_args.append('-Wno-unused-variable') +- extra_compile_args.append('-std=c++11') ++ extra_compile_args.append('-std=c++14') + + if sys.platform == 'darwin': + extra_compile_args.append('-Wno-shorten-64-to-32') diff --git a/user/protobuf/python-311.patch b/user/protobuf/python-311.patch new file mode 100644 index 000000000..f0a68dadd --- /dev/null +++ b/user/protobuf/python-311.patch @@ -0,0 +1,134 @@ +https://github.com/protocolbuffers/protobuf/pull/10403 + +From da973aff2adab60a9e516d3202c111dbdde1a50f Mon Sep 17 00:00:00 2001 +From: Alexander Shadchin <alexandr.shadchin@gmail.com> +Date: Sun, 14 Aug 2022 21:13:49 +0300 +Subject: [PATCH] Fix build with Python 3.11 + +The PyFrameObject structure members have been removed from the public C API. +--- + python/google/protobuf/pyext/descriptor.cc | 75 ++++++++++++++++++---- + 1 file changed, 62 insertions(+), 13 deletions(-) + +diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc +index fc83acf01a7..fc97b0fa6c1 100644 +--- a/python/google/protobuf/pyext/descriptor.cc ++++ b/python/google/protobuf/pyext/descriptor.cc +@@ -58,6 +58,37 @@ + : 0) \ + : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) + ++#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION) ++static PyCodeObject* PyFrame_GetCode(PyFrameObject *frame) ++{ ++ Py_INCREF(frame->f_code); ++ return frame->f_code; ++} ++ ++static PyFrameObject* PyFrame_GetBack(PyFrameObject *frame) ++{ ++ Py_XINCREF(frame->f_back); ++ return frame->f_back; ++} ++#endif ++ ++#if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION) ++static PyObject* PyFrame_GetLocals(PyFrameObject *frame) ++{ ++ if (PyFrame_FastToLocalsWithError(frame) < 0) { ++ return NULL; ++ } ++ Py_INCREF(frame->f_locals); ++ return frame->f_locals; ++} ++ ++static PyObject* PyFrame_GetGlobals(PyFrameObject *frame) ++{ ++ Py_INCREF(frame->f_globals); ++ return frame->f_globals; ++} ++#endif ++ + namespace google { + namespace protobuf { + namespace python { +@@ -96,48 +127,66 @@ bool _CalledFromGeneratedFile(int stacklevel) { + // This check is not critical and is somewhat difficult to implement correctly + // in PyPy. + PyFrameObject* frame = PyEval_GetFrame(); ++ PyCodeObject* frame_code = nullptr; ++ PyObject* frame_globals = nullptr; ++ PyObject* frame_locals = nullptr; ++ bool result = false; ++ + if (frame == nullptr) { +- return false; ++ goto exit; + } ++ Py_INCREF(frame); + while (stacklevel-- > 0) { +- frame = frame->f_back; ++ PyFrameObject* next_frame = PyFrame_GetBack(frame); ++ Py_DECREF(frame); ++ frame = next_frame; + if (frame == nullptr) { +- return false; ++ goto exit; + } + } + +- if (frame->f_code->co_filename == nullptr) { +- return false; ++ frame_code = PyFrame_GetCode(frame); ++ if (frame_code->co_filename == nullptr) { ++ goto exit; + } + char* filename; + Py_ssize_t filename_size; +- if (PyString_AsStringAndSize(frame->f_code->co_filename, ++ if (PyString_AsStringAndSize(frame_code->co_filename, + &filename, &filename_size) < 0) { + // filename is not a string. + PyErr_Clear(); +- return false; ++ goto exit; + } + if ((filename_size < 3) || + (strcmp(&filename[filename_size - 3], ".py") != 0)) { + // Cython's stack does not have .py file name and is not at global module + // scope. +- return true; ++ result = true; ++ goto exit; + } + if (filename_size < 7) { + // filename is too short. +- return false; ++ goto exit; + } + if (strcmp(&filename[filename_size - 7], "_pb2.py") != 0) { + // Filename is not ending with _pb2. +- return false; ++ goto exit; + } + +- if (frame->f_globals != frame->f_locals) { ++ frame_globals = PyFrame_GetGlobals(frame); ++ frame_locals = PyFrame_GetLocals(frame); ++ if (frame_globals != frame_locals) { + // Not at global module scope +- return false; ++ goto exit; + } + #endif +- return true; ++ result = true; ++exit: ++ Py_XDECREF(frame_globals); ++ Py_XDECREF(frame_locals); ++ Py_XDECREF(frame_code); ++ Py_XDECREF(frame); ++ return result; + } + + // If the calling code is not a _pb2.py file, raise AttributeError. |